diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index ca01ef32b4..995c609667 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -37,5 +37,6 @@ The below URLs can be updated where the placeholders are, look for `{YOUR GITHUB - [ ] Associated it with relevant [issues](https://github.com/Azure/Enterprise-Scale/issues), for tracking and closure. - [ ] Ensured my code/branch is up-to-date with the latest changes in the `main` [branch](https://github.com/Azure/Enterprise-Scale/tree/main) - [ ] Performed testing and provided evidence. +- [ ] Ensured [contribution guidance](https://github.com/Azure/Enterprise-Scale/wiki/ALZ-Contribution-Guide) is followed. - [ ] Updated relevant and associated documentation. - [ ] Updated the ["What's New?"](https://github.com/Azure/Enterprise-Scale/wiki/Whats-new) wiki page (located: `/docs/wiki/whats-new.md`) diff --git a/.github/workflows/update-portal.yml b/.github/workflows/update-portal.yml index c48bc82a3d..9ab0fe148f 100644 --- a/.github/workflows/update-portal.yml +++ b/.github/workflows/update-portal.yml @@ -57,6 +57,9 @@ jobs: - name: Update policies run: bicep build ./src/templates/policies.bicep --outfile ./eslzArm/managementGroupTemplates/policyDefinitions/policies.json + - name: Update roles + run: bicep build ./src/templates/roles.bicep --outfile ./eslzArm/managementGroupTemplates/roleDefinitions/customRoleDefinitions.json + - name: Check git status run: | echo "==> Check git status..." diff --git a/.github/workflows/wiki-sync.yml b/.github/workflows/wiki-sync.yml index 7da0dfd133..10231d32ae 100644 --- a/.github/workflows/wiki-sync.yml +++ b/.github/workflows/wiki-sync.yml @@ -61,5 +61,5 @@ jobs: echo "Pushing changes to origin..." git add . git commit -m "$github_commit_message [$GITHUB_ACTOR/${GITHUB_SHA::8}]" - git push --set-upstream https://$GITHUB_TOKEN@github.com/$wiki_target_repo.git master + git push --set-upstream "https://$GITHUB_TOKEN@github.com/$wiki_target_repo.git" master working-directory: ${{ env.wiki_target_repo }} diff --git a/README.md b/README.md index cc5bf439d7..a82783cdf0 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,11 @@ # Enterprise-Scale - Reference Implementation -## Navigation Menu - -* [What's New?](https://github.com/Azure/Enterprise-Scale/wiki/Whats-new) -* [Community Calls](https://github.com/Azure/Enterprise-Scale/wiki/Community-Calls) -* [Enterprise-Scale Landing Zones - User Guide](https://github.com/Azure/Enterprise-Scale/wiki#enterprise-scale-landing-zones-user-guide) -* [Enterprise-Scale Architecture](./docs/EnterpriseScale-Architecture.md) -* [Telemetry Tracking Using Customer Usage Attribution (PID)](https://github.com/Azure/Enterprise-Scale/wiki/Deploying-Enterprise-Scale-CustomerUsage) -* [Configure Azure permission for ARM Template deployments](./docs/EnterpriseScale-Setup-azure.md) -* [Deploy Reference Implementation](./docs/EnterpriseScale-Deploy-reference-implentations.md) - * [Policies included in Azure landing zones reference implementations](https://github.com/Azure/Enterprise-Scale/wiki/ALZ-Policies) - * [Contoso Reference - Scope and Design](./docs/reference/contoso/Readme.md) - * [AdventureWorks Reference - Scope and Design](./docs/reference/adventureworks/README.md) - * [WingTip Reference - Scope and Design](./docs/reference/wingtip/README.md) - * [Trey Research Reference - Scope and Design](./docs/reference/treyresearch/README.md) -* [Create Landing Zones](./docs/EnterpriseScale-Deploy-landing-zones.md) -* [Deploy workloads into Landing Zones](./workloads) -* [Getting started with Infrastructure-as-Code](https://github.com/Azure/AzOps-Accelerator/wiki) -* [Azure Landing Zones Deprecated Services](./docs/wiki/ALZ-Deprecated-Services.md) -* [Known Issues](./docs/EnterpriseScale-Known-Issues.md) -* [How Do I Contribute?](./docs/EnterpriseScale-Contribution.md) -* [Frequently Asked Questions (FAQ)](https://github.com/Azure/Enterprise-Scale/wiki/FAQ) -* [Roadmap](./docs/EnterpriseScale-Roadmap.md) -* [Microsoft Support Policy](./SUPPORT.md) +[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/azure/enterprise-scale.svg)](http://isitmaintained.com/project/azure/enterprise-scale "Average time to resolve an issue") +[![Percentage of issues still open](http://isitmaintained.com/badge/open/azure/enterprise-scale.svg)](http://isitmaintained.com/project/azure/enterprise-scale "Percentage of issues still open") + +## User documentation + +To find out more about the Azure landing zones reference implementation, please refer to the [documentation on our Wiki](https://github.com/Azure/Enterprise-Scale/wiki) --- @@ -32,7 +15,7 @@ The Enterprise-Scale architecture provides prescriptive guidance coupled with Az The Enterprise-Scale architecture is modular by design and allows organizations to start with foundational landing zones that support their application portfolios, and the architecture enables organizations to start as small as needed and scale alongside their business requirements regardless of scale point. -![hippo](./docs/media/ESLZ.gif) +![Animated image showing the modularity of Azure landing zones](./docs/wiki/media/ESLZ.gif) --- @@ -52,7 +35,7 @@ The Enterprise-Scale reference implementations in this repository are intended t | Be aligned with cloud provider’s platform roadmap | Yes | | UI Experience and simplified setup | Yes, Azure portal | | All critical services are present and properly configured according to recommend best practices for identity & access management, governance, security, network and logging | Yes, using a multi-subscription design, aligned with Azure platform roadmap | -| Automation capabilities (IaC/DevOps) | Yes: ARM, Policy, GitHub/Azure DevOps CICD pipeline option included | +| Automation capabilities (IaC/DevOps) | Yes: ARM, Policy, GitHub/Azure DevOps CI/CD pipeline option included | | Provides long-term self-sufficiency | Yes, enterprise-scale architecture -> 1:N landing zones. Approach & architecture prepare the customer for long-term self-sufficiency, the RIs are there to get you started | | Enables migration velocity across the organization | Yes, enterprise-scale architecture -> 1:N landing zones, Architecture includes designs for segmentation and separation of duty to empower teams to act within appropriate landing zones | | Achieves operational excellence | Yes. Enables autonomy for platform and application teams with a policy driven governance and management | @@ -63,7 +46,7 @@ To fully leverage this reference implementation in this repository, readers must It is also assumed that readers have a broad understanding of key Azure constructs and services in order to fully contextualize the prescriptive recommendations contained within Enterprise-Scale. ## Deploying Enterprise-Scale Architecture in your own environment @@ -84,7 +67,7 @@ The Enterprise-Scale architecture is modular by design and allows customers to s This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us -the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com. +the rights to use your contribution. For details, visit [Contributor License Agreement (CLA)](https://cla.opensource.microsoft.com). When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions diff --git a/SECURITY.md b/SECURITY.md index f7b89984f0..f336c60304 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -4,7 +4,7 @@ Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). -If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc751383(v=technet.10)), please report it to us as described below. +If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://docs.microsoft.com/previous-versions/tn-archive/cc751383(v=technet.10)), please report it to us as described below. ## Reporting Security Issues @@ -12,19 +12,19 @@ If you believe you have found a security vulnerability in any Microsoft-owned re Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report). -If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/en-us/msrc/pgp-key-msrc). +If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/msrc/pgp-key-msrc). -You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc). +You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc). Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: - * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) - * Full paths of source file(s) related to the manifestation of the issue - * The location of the affected source code (tag/branch/commit or direct URL) - * Any special configuration required to reproduce the issue - * Step-by-step instructions to reproduce the issue - * Proof-of-concept or exploit code (if possible) - * Impact of the issue, including how an attacker might exploit the issue +* Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) +* Full paths of source file(s) related to the manifestation of the issue +* The location of the affected source code (tag/branch/commit or direct URL) +* Any special configuration required to reproduce the issue +* Step-by-step instructions to reproduce the issue +* Proof-of-concept or exploit code (if possible) +* Impact of the issue, including how an attacker might exploit the issue This information will help us triage your report more quickly. @@ -36,6 +36,6 @@ We prefer all communications to be in English. ## Policy -Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd). +Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/msrc/cvd). \ No newline at end of file diff --git a/SUPPORT.md b/SUPPORT.md index b504dcfe35..c6f230772f 100644 --- a/SUPPORT.md +++ b/SUPPORT.md @@ -2,7 +2,7 @@ ## Microsoft Support Policy -If issues are encountered when deploying these reference implementations users will be able to engage Microsoft support via their usual channels. Please provide corelation IDs where possible when contacting support to be able to investigate issue effectively and in timely fashion. For instruction on how to get deployments and correlation ID, please follow this link [here](https://docs.microsoft.com/en-us/azure/azure-resource-manager/templates/deployment-history?tabs=azure-portal#get-deployments-and-correlation-id). +If issues are encountered when deploying these reference implementations users will be able to engage Microsoft support via their usual channels. Please provide corelation IDs where possible when contacting support to be able to investigate issue effectively and in timely fashion. For instruction on how to get deployments and correlation ID, please follow this link [here](https://docs.microsoft.com/azure/azure-resource-manager/templates/deployment-history?tabs=azure-portal#get-deployments-and-correlation-id). Following list of issues are within the scope of Microsoft support: diff --git a/docs/Deploy/deploy-policy-driven-routing.md b/docs/Deploy/deploy-policy-driven-routing.md index 0c4b72a35d..b2dcae97b2 100644 --- a/docs/Deploy/deploy-policy-driven-routing.md +++ b/docs/Deploy/deploy-policy-driven-routing.md @@ -1,4 +1,5 @@ # Policy-driven routing configuration in hub and spoke networks + The policy `Deploy a route table with specific user defined routes` allows applying a customer-defined routing configuration to in-scope VNets. For each in-scope VNet, the policy checks the existence of a route table containing a set of customer-defined UDRs; and deploys it if it does not exist. The route table is deployed to the same resource group as the VNet evaluated against the policy. The route table deployed by the policy must be manually associated to subnets. The main usage scenario for the policy is automated routing configuration in Enterprise-Scale hub and spoke topologies (the reference architecture for Enterprise Scale with hub and spoke is documented [here](https://github.com/Azure/Enterprise-Scale/tree/main/docs/reference/adventureworks)). By assigning the policy to landing zone subscriptions that contain the spoke VNet(s), it allows enforcing routing rules such as: @@ -12,9 +13,10 @@ The main usage scenario for the policy is automated routing configuration in Ent - Route all traffic from spoke VNet to shared services in the hub via the hub’s firewall cluster. The policy supports the parameters documented below. + - **effect**: A `String` that defines the effect of the policy. Allowed values are `DeployIfNotExist` (default) and `Disabled`. -- **requiredRoutes**: An `Array` of `String` objects. Each `String` object defines a User-Defined Route (UDR) in the custom route table deployed by the policy. The format is `"address-prefix;next-hop-type;next-hop-ip-address"`. The next-hop IP address must be provided on when the next hop type is "VirtualAppliance". Allowed values for the next hop type field are documented [here](https://docs.microsoft.com/en-us/azure/virtual-network/virtual-networks-udr-overview#next-hop-types-across-azure-tools). This is an example of a *requiredRoutes* array that defines four UDRs: +- **requiredRoutes**: An `Array` of `String` objects. Each `String` object defines a User-Defined Route (UDR) in the custom route table deployed by the policy. The format is `"address-prefix;next-hop-type;next-hop-ip-address"`. The next-hop IP address must be provided on when the next hop type is "VirtualAppliance". Allowed values for the next hop type field are documented [here](https://docs.microsoft.com/azure/virtual-network/virtual-networks-udr-overview#next-hop-types-across-azure-tools). This is an example of a *requiredRoutes* array that defines four UDRs: ```json [ @@ -24,6 +26,7 @@ The policy supports the parameters documented below. "192.168.2.0/24;VnetLocal" ] ``` + - **vnetRegion**: A `String` that defines the region of the `Microsoft.Network/virtualNetworks` resources that are evaluated against the policy. Only VNets in the specified region are evaluated against the policy. This parameter enables multiple assignments to enforce different routing policies in different regions. -- **routeTableName**: A `String` that defines the name of the custom route table automatically deployed by the policy (when one that contains all the *requiredRoutes* is found). -- **disableBgpPropagation**: A `Boolean` that defines the value of the *disableBgpRoutePropagation* property of the deployed route table. The default value is `false`. \ No newline at end of file +- **routeTableName**: A `String` that defines the name of the custom route table automatically deployed by the policy (when one that contains all the *requiredRoutes* is found). +- **disableBgpPropagation**: A `Boolean` that defines the value of the *disableBgpRoutePropagation* property of the deployed route table. The default value is `false`. diff --git a/docs/Deploy/es-schema.md b/docs/Deploy/es-schema.md index 1ba447e53b..c3ec6e0a32 100644 --- a/docs/Deploy/es-schema.md +++ b/docs/Deploy/es-schema.md @@ -10,7 +10,7 @@ This article will help you to familiarize with the [Enterprise-Scale ARM templat ## ARM template objectives for Enterprise-Scale -Some of the key [design principles](https://docs.microsoft.com/en-us/azure/cloud-adoption-framework/ready/enterprise-scale/design-principles) of Enterprise-Scale is to have a single control and management plane, be Azure native and aligned to the platform roadmap, and employ Azure Policy to enable policy driven governance and management. That means we rely on platform capabilities in order to compose and deploy the Enterprise-Scale architecture end-2-end. +Some of the key [design principles](https://docs.microsoft.com/azure/cloud-adoption-framework/ready/enterprise-scale/design-principles) of Enterprise-Scale is to have a single control and management plane, be Azure native and aligned to the platform roadmap, and employ Azure Policy to enable policy driven governance and management. That means we rely on platform capabilities in order to compose and deploy the Enterprise-Scale architecture end-2-end. The objectives includes: diff --git a/docs/ESLZ-Policies.md b/docs/ESLZ-Policies.md index 40c8f4708a..5dfd4c1c21 100644 --- a/docs/ESLZ-Policies.md +++ b/docs/ESLZ-Policies.md @@ -1,3 +1,3 @@ -## This page has moved +# This page has moved to our Wiki -Please refer to [Policies included in Azure landing zones reference implementations](./wiki/ALZ-Policies.md) +Please refer to [Policies included in Azure Landing Zones reference implementations](https://github.com/Azure/Enterprise-Scale/wiki/ALZ-Policies) diff --git a/docs/EnterpriseScale-Architecture.md b/docs/EnterpriseScale-Architecture.md index 2f729f5afc..c1fa4a04ca 100644 --- a/docs/EnterpriseScale-Architecture.md +++ b/docs/EnterpriseScale-Architecture.md @@ -1,53 +1,3 @@ +# This page has moved to our Wiki -# Enterprise-Scale Architecture - -The principle challenges facing enterprise customers adopting Azure are 1) how to allow applications (legacy or modern) to seamlessly move at their own pace, and 2) how to provide secure and streamlined operations, management, and governance across the entire platform and all encompassed applications. To address these challenges, customers require a forward looking and Azure-native design approach, which in the context of this playbook is represented by the Enterprise-Scale architecture. - -## What is the Enterprise-Scale Architecture - -The Enterprise-Scale architecture represents the strategic design path and target technical state for the customer's Azure environment. It will continue to evolve in lockstep with the Azure platform and is ultimately defined by the various design decisions the customer organization must make to define their Azure journey. - -It is important to highlight that not all enterprises adopt Azure in the same way, and as a result the Enterprise-Scale architecture may vary between customers. Ultimately, the technical considerations and design recommendations presented within this playbook may yield different trade-offs based on the customer scenario. Some variation is therefore expected, but provided core recommendations are followed, the resultant target architecture will position the customer on a path to sustainable scale. - -## Landing Zones Definition - -Within the context of the Enterprise-Scale architecture, a "Landing Zone" is a logical construct capturing everything that must be true to enable application migrations and development at an Enterprise-Scale in Azure. It considers all platform Resources that are required to support the customer's application portfolio and does not differentiate between IaaS or PaaS. - -Every large enterprise software estate will encompass a myriad of application archetypes and each Landing Zone essentially represents the common elements, such as networking and IAM, that are shared across instances of these archetypes and must be in place to ensure that migrating applications have access to requisite components when deployed. Each Landing Zone must consequently be designed and deployed in accordance with the requirements of archetypes within the customer's application portfolio. - -The principle purpose of the "Landing Zones" is therefore to ensure that when an application lands on Azure, the required "plumbing" is already in place, providing greater agility and compliance with enterprise security and governance requirements. - ---- - -_Using an analogy, this is similar to how city utilities such as water, gas, and electricity are accessible before new houses are constructed. In this context, the network, IAM, policies, management, and monitoring are shared 'utility' services that must be readily available to help streamline the application migration process._ - ---- - -# Design Principles - -The Enterprise-Scale architecture is based on the [five design principles](https://docs.microsoft.com/en-us/azure/cloud-adoption-framework/ready/enterprise-scale/design-principles). These principles serve as a compass for subsequent design decisions across critical technical domains. Readers and users of the reference implementation are strongly advised to familiarize themselves with these principles to better understand their impact and the trade-offs associated with non-adherence. - -* [Subscription democratization](https://docs.microsoft.com/en-us/azure/cloud-adoption-framework/ready/enterprise-scale/design-principles?branch#subscription-democratization) -* [Policy-driven governance](https://docs.microsoft.com/en-us/azure/cloud-adoption-framework/ready/enterprise-scale/design-principles#policy-driven-governance) -* [Single control and management plane](https://docs.microsoft.com/en-us/azure/cloud-adoption-framework/ready/enterprise-scale/design-principles#single-control-and-management-plane) -* [Application-centric and archetype-neutral](https://docs.microsoft.com/en-us/azure/cloud-adoption-framework/ready/enterprise-scale/design-principles?#application-centric-and-archetype-neutral) -* [Aligning Azure-native design and road maps](https://docs.microsoft.com/en-us/azure/cloud-adoption-framework/ready/enterprise-scale/design-principles#align-azure-native-design-and-roadmaps) - -# Design Guidelines - -At the centre of the Enterprise-Scale architecture lies a critical design path, comprised of fundamental design topics with heavily interrelated and dependent design decisions. This repository provides design guidance across these architecturally significant technical domains to support the critical design decisions which must occur to define the Enterprise-Scale architecture. For each of the considered domains, readers should review the provided considerations and recommendations, using them to structure and drive designs within each area. - -## Critical Design Areas - -The [eight critical design areas](https://docs.microsoft.com/en-us/azure/cloud-adoption-framework/ready/landing-zone/design-areas) are intended to support the translation of customer requirements to Azure constructs and capabilities, to address the mismatch between on-premises infrastructure and cloud-design which typically creates dissonance and friction with respect to the Enterprise-Scale definition and Azure adoption. - -The impact of decisions made within these critical areas will reverberate across the Enterprise-Scale architecture and influence other decisions. Readers and reference implementation users are strongly advised to familiarize themselves with these eight areas, to better understand the consequences of encompassed decisions, which may later produce trade-offs within related areas. - -* [Billing and Active Directory tenants](https://docs.microsoft.com/en-us/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-ad-tenant) -* [Identity and access management](https://docs.microsoft.com/en-us/azure/cloud-adoption-framework/ready/landing-zone/design-area/identity-access) -* [Network topology and connectivity](https://docs.microsoft.com/en-us/azure/cloud-adoption-framework/ready/landing-zone/design-area/network-topology-and-connectivity) -* [Resource organization](https://docs.microsoft.com/en-us/azure/cloud-adoption-framework/ready/landing-zone/design-area/resource-org) -* [Security](https://docs.microsoft.com/en-us/azure/cloud-adoption-framework/ready/landing-zone/design-area/security) -* [Management](https://docs.microsoft.com/en-us/azure/cloud-adoption-framework/ready/landing-zone/design-area/management) -* [Governance](https://docs.microsoft.com/en-us/azure/cloud-adoption-framework/ready/landing-zone/design-area/governance) -* [Platform automation and DevOps](https://docs.microsoft.com/en-us/azure/cloud-adoption-framework/ready/landing-zone/design-area/platform-automation-devops) +Please refer to [Enterprise-Scale Architecture](https://github.com/Azure/Enterprise-Scale/wiki/ALZ-Architecture) diff --git a/docs/EnterpriseScale-Contribution.md b/docs/EnterpriseScale-Contribution.md index 390b04b363..e07a2fc531 100644 --- a/docs/EnterpriseScale-Contribution.md +++ b/docs/EnterpriseScale-Contribution.md @@ -1,62 +1,3 @@ +# This page has moved to our Wiki -## Contribution Guide - -### Enterprise-Scale Committee -The Enterprise-Scale Committee and its members (aka Committee Members) are the primary caretakers of the Enterprise-Scale and AzOps repos including language, design, and reference implementations. - -### Current Committee Members - -- Uday Pandya @uday31in -- Kristian Nese @krnese -- Victor Arzate @victorar -- Johan Dahlbom @daltondhcp -- Lyon Till @ljtill -- Niels Buit @nielsams -- Hansjoerg Scherer @hjscherer -- Callum Coffin @CalCof - -### Committee Member Responsibilities - -Committee Members are responsible for reviewing and approving RFCs proposing new features or design changes. - -The initial Enterprise Committee consists of Microsoft employees. It is expected that over time, community will grow and new community members will join Committee Members. Membership is heavily dependent on the level of contribution and expertise: individuals who contribute in meaningful ways to the project will be recognized accordingly. - -At any point in time, a Committee Member can nominate a strong community member to join the Committee. Nominations should be submitted in the form of RFCs detailing why that individual is qualified and how they will contribute. After the RFC has been discussed, a unanimous vote will be required for the new Committee Member to be confirmed. - -### Contribution scope for Enterprise-Scale - -The following is the scope of contributions to this repository: - -As the Azure platform evolves and new services and features are validated in production with customers, the design guidelines will be updated in the overall architecture context. - -With new Services, Resources, Resource properties and API versions, the implementation guide and reference implementation must be updated as appropriate. -Primarily, the code contribution would be centered on Azure Policy definitions and Azure Policy assignments for for Contoso Implementation. - -Submit a pull request for documentation updates using the following template 'placeholder'. - -#### How to submit Pull Request to upstream repo - -1. Create a new branch based on upstream/main by executing following command - - ```shell - git checkout -b feature upstream/main - ``` - -2. Checkout the file(s) from your working branch that you may want to include in PR - - ```shell - #substitute file name as appropriate. below example - git checkout feature: .\.docs\Deploy\Deploy-lz.md - ``` - -3. Push your Git branch to your origin - - ```shell - git push origin -u - ``` - -4. Create a pull request from upstream to your remote main - -### Code of Conduct - -We are working hard to build strong and productive collaboration with our passionate community. We heard you loud and clear. We are working on set of principles and guidelines with Do's and Don'ts. +Please refer to [Contribution Guide](https://github.com/Azure/Enterprise-Scale/wiki/ALZ-Contribution) diff --git a/docs/EnterpriseScale-Deploy-landing-zones.md b/docs/EnterpriseScale-Deploy-landing-zones.md index 9604569c4e..2ff347791e 100644 --- a/docs/EnterpriseScale-Deploy-landing-zones.md +++ b/docs/EnterpriseScale-Deploy-landing-zones.md @@ -1,42 +1,3 @@ -# Create Landing Zone(s) - -It is now time to turn the lights ON :bulb: - -At this point you have the necessary platform setup configured to support one or many Landing Zone(s) with the required definitions (Roles, Policies and PolicySet) and assignments (Roles and Policies). - -Provisioning Landing Zone(s) will mean either **creating a new subscription** or **moving an existing subscription** to the desired Management Group and the platform will do the rest. In large environments with 10s and 100s of Landing Zones, the platform team can also delegate Landing Zone(s) to the respective business units and/or application portfolio owners while being confident that security, compliance and monitoring requirements are being met. Furthermore, the platform team may also delegate the necessary access permissions such as: - -1) IAM roles to create new subscriptions -2) Place subscriptions in the appropriate Management Groups for business units and/or application portfolio owners to provide self-service access to create their own Landing Zone(s). - -## Create or move a Subscription under the Landing Zone Management Group - -Depending upon the reference implementation that's deployed, navigate to the appropriate Management Group under the "Landing Zones" Management Group and create or move an existing subscription. This can be done via the Azure Portal or PowerShell/CLI. - -Business units and/or application portfolio owners can use their preferred tool chain - ARM, PowerShell, Terraform, Portal, CLI etc. for subsequent resource deployments within their respective Landing Zone(s). - -### Create new subscriptions into the **Landing zones** > **Corp** or **Online** Management Group - -1. In the Azure portal, navigate to Subscriptions -2. Click 'Add', and complete the required steps in order to create a new subscription. -3. When the subscription has been created, go to Management Groups and move the subscription into the **Landing zones** > **Corp** or **Online** Management Group -4. Assign RBAC permissions for the application team/user(s) who will be deploying resources in to the newly created subscription - -### Move existing subscriptions into the **Landing zones** > **Corp** or **Online** Management Group - -1. In the Azure portal, navigate to Management Groups -2. Locate the subscription you want to move, and move it in to the **Landing zones** > **Corp** or **Online** Management Group -3. Assign RBAC permissions for the application team/user(s) who will be deploying resources in to the subscription - -## Create Enterprise-Scale Landing Zones using the Azure Portal - -The following deployment experiences can be leveraged to create multiple landing zones (subscriptions) and target individual Management Groups (e.g., 'online', 'corp' etc.). - -To use the ARM templates below to create new subscriptions, you must have Management Group Contributor or Owner permissions on the Management Group where you will invoke the deployment and also on the targeted Management Groups for the new subscriptions, as well as subscription write permissions on the billing account. - -| Agreement types | ARM Template | Description -|:-------------------------|:-------------|:--------------| -| Enterprise Agreement (EA) |[![Deploy To Azure](https://docs.microsoft.com/en-us/azure/templates/media/deploy-to-azure.svg)](https://portal.azure.com/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2Fdocs%2Freference%2Flzs%2FarmTemplates%2Feslz.json/createUIDefinitionUri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2Fdocs%2Freference%2Flzs%2FarmTemplates%2Fportal-eslz.json) | Create 'N' number of subscriptions into multiple Management Groups -| Enterprise Agreement (EA) |[![Deploy To Azure](https://docs.microsoft.com/en-us/azure/templates/media/deploy-to-azure.svg)](https://portal.azure.com/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2Fexamples%2Flanding-zones%2Fsubscription-with-rbac%2FsubscriptionWithRbac.json/createUIDefinitionUri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2Fexamples%2Flanding-zones%2Fsubscription-with-rbac%2Fportal-subscriptionWithRbac.json)| Create a subscription with RBAC for SPN - +# This page has moved to our Wiki +Please refer to [Create Landing Zone(s)](https://github.com/Azure/Enterprise-Scale/wiki/ALZ-Deploy-landing-zones) diff --git a/docs/EnterpriseScale-Deploy-reference-implentations.md b/docs/EnterpriseScale-Deploy-reference-implentations.md index 83999634d1..ec91f31889 100644 --- a/docs/EnterpriseScale-Deploy-reference-implentations.md +++ b/docs/EnterpriseScale-Deploy-reference-implentations.md @@ -1,30 +1,3 @@ -# Deploy Enterprise-Scale Reference implementation in your own environment +# This page has moved to our Wiki -This section will guide you through the process of deploying an Enterprise-Scale reference implementation in your own environment. - -## What is an Enterprise-Scale Reference Implementation? - -The Enterprise-Scale design principles and reference implementations can be adopted by all customers no matter what the size or history of their Azure estate. The following reference implementations target the most common customer scenarios for adopting Enterprise-Scale. - -## Deploy a Reference Implementation - -| Reference implementation | Description | ARM Template | Link | -|:-------------------------|:-------------|:-------------|------| -| Contoso | On-premises connectivity using Azure vWAN |[![Deploy To Azure](https://docs.microsoft.com/en-us/azure/templates/media/deploy-to-azure.svg)](https://portal.azure.com/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2FeslzArm%2FeslzArm.json/uiFormDefinitionUri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2FeslzArm%2Feslz-portal.json) | [Detailed description](./reference/contoso/Readme.md) | -| AdventureWorks | On-premises connectivity with Hub & Spoke |[![Deploy To Azure](https://docs.microsoft.com/en-us/azure/templates/media/deploy-to-azure.svg)](https://portal.azure.com/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2FeslzArm%2FeslzArm.json/uiFormDefinitionUri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2FeslzArm%2Feslz-portal.json) | [Detailed description](./reference/adventureworks/README.md) | -| WingTip | Azure without hybrid connectivity |[![Deploy To Azure](https://docs.microsoft.com/en-us/azure/templates/media/deploy-to-azure.svg)](https://portal.azure.com/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2FeslzArm%2FeslzArm.json/uiFormDefinitionUri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2FeslzArm%2Feslz-portal.json) | [Detailed description](./reference/wingtip/README.md) | -| Trey Research | For small enterprises | [![Deploy To Azure](https://docs.microsoft.com/en-us/azure/templates/media/deploy-to-azure.svg)](https://portal.azure.com/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2Fdocs%2Freference%2Ftreyresearch%2FarmTemplates%2Fes-lite.json/createUIDefinitionUri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2Fdocs%2Freference%2Ftreyresearch%2FarmTemplates%2Fportal-es-lite.json) | [Detailed description](./reference/treyresearch/README.md) | - -> The Bicep version is now available in Public Preview here: [https://github.com/Azure/ALZ-Bicep](https://github.com/Azure/ALZ-Bicep) - -An Enterprise-Scale reference implementation is rooted in the principle that **Everything in Azure is a Resource**. All of the reference scenarios leverage native **Azure Resource Manager (ARM)** to describe and manage their resources as part of their target state architecture at-scale. - -Reference implementations enable security, monitoring, networking, and any other plumbing needed for landing zones (i.e. Subscriptions) autonomously through policy enforcement. Companies will deploy the Azure environment with ARM templates to create the necessary structure for management and networking to declare a desired goal state. All scenarios will apply the principle of "Policy Driven Governance" for landing zones by using Azure Policy. The benefits of a policy-driven approach are many but the most significant are: - -1. Platform can provide an orchestration capability to bring target resources (in this case a subscription) to a desired goal state. - -2. Continuous conformance to ensure all platform-level resources are compliant. Because the platform is aware of the goal state, the platform can assist with the monitoring and remediation of resources throughout their life-cycle. - -3. Platform enables autonomy regardless of the customer's scale point. - -To know and learn more about ARM templates used for above reference implementation, please follow [this](./Deploy/es-schema.md) article. +Please refer to [Deploy Enterprise-Scale Reference implementation in your own environment](https://github.com/Azure/Enterprise-Scale/wiki/ALZ-Deploy-reference-implementations) diff --git a/docs/EnterpriseScale-Deploy-workloads.md b/docs/EnterpriseScale-Deploy-workloads.md index a84a9ed5a1..38a0ab2b6d 100644 --- a/docs/EnterpriseScale-Deploy-workloads.md +++ b/docs/EnterpriseScale-Deploy-workloads.md @@ -1,44 +1,3 @@ -# Deploy workloads into the landing zones +# This page has moved to our Wiki -At this point you have the necessary platform setup and landing zones (subscriptions) created and placed into their respective management groups, being secure, governed, monitored, and enabled for autonomy and are ready for your application teams to do workload deployments, migrations, and net-new development to their landing zones. - -The following workloads outlined here provides best-practices, and curated deployment experiences for your application teams to successfully deploy them into their landing zones (online, corp). - -## AKS (Kubernetes) - -Deploy Kubernetes to Azure and integrate with ARM, Azure AD, Azure Policy, and Azure Monitor to ensure you have a production ready Kubernetes cluster in your landing zone -a -| Landing zone | ARM Template | Details | -|:-------------------------|:-------------|:-----------| -| Online |[![Deploy To Azure](https://docs.microsoft.com/en-us/azure/templates/media/deploy-to-azure.svg)](https://portal.azure.com/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2Fworkloads%2FAKS%2FarmTemplates%2Fonline-aks.json/createUIDefinitionUri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2Fworkloads%2FAKS%2FarmTemplates%2Fportal-online-aks.json) | [Detailed description](../workloads/AKS/README.md) -| Corp | Coming soon | Detailed description - - -### SAP (coming soon) - -Details coming soon - -| Landing zone | ARM Template | Details | -|:-------------------------|:-------------|:-----------| -| Online | Coming soon -| Corp | Coming soon - - -### Windows Virtual Desktop (coming soon) - -Details coming soon - -| Landing zone | ARM Template | Details | -|:-------------------------|:-------------|:-----------| -| Online | Coming soon -| Corp | Coming soon - - -### Data and Analytics (coming soon) - -Details coming soon - -| Landing zone | ARM Template | Details -|:-------------------------|:-------------|:-----------| -| Online | Coming soon -| Corp | Coming soon \ No newline at end of file +Please refer to [Deploy workloads into the landing zones](https://github.com/Azure/Enterprise-Scale/wiki/ALZ-Deploy-workloads) diff --git a/docs/EnterpriseScale-Known-Issues.md b/docs/EnterpriseScale-Known-Issues.md index 029dcb61cc..2f0eec16a0 100644 --- a/docs/EnterpriseScale-Known-Issues.md +++ b/docs/EnterpriseScale-Known-Issues.md @@ -1,26 +1,3 @@ -# Reference Implementation - Known Issues +# This page has moved to our Wiki -The list below summarizes the known issues currently being worked on by the Enterprise-Scale team. - -These have been discovered whilst running the reference implementation, and customers may come across them when implementing Enterprise-Scale to build and operationalize their Azure platform. - -Some of these issues may be resolved in future release, while others require input from specific Azure product teams. - -## Deploying the reference implementation fails due to 'Policy cannot be found (404)' - -### Area -ARM backend storage - -### Issue -When deploying to a region that is paired (e.g., EastUS, which is paired with WestUS), resources deployed in deployment 1 who's referenced in deployment 2 may fail due to replication latency in ARM backend storage. This will cause the overall deployment to fail - -### Status -While this is being fixed, it is recommended to re-run the deployment of the reference implementation with the same input parameter, and the deployment should succeed. - -## Unsupported number of Tenants in context: x TenantID(s) - -### Issue -We currently do not support Initialization across multiple Tenants.
Clear your AzContext and run `Connect-AzAccount` with the service principal that was created earlier. - -### Status -No fix as of yet. +Please refer to [Reference Implementation - Known Issues](https://github.com/Azure/Enterprise-Scale/wiki/ALZ-Known-Issues) diff --git a/docs/EnterpriseScale-Roadmap.md b/docs/EnterpriseScale-Roadmap.md index 86f2f442fa..a433fee94e 100644 --- a/docs/EnterpriseScale-Roadmap.md +++ b/docs/EnterpriseScale-Roadmap.md @@ -1,19 +1,3 @@ +# This page has moved to our Wiki -# Roadmap - -We intend to update the content within this repo in alignment with Azure Semester planning. - -| Milestone | Scope | Status | -|----------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------| -| Design Principles and Architecture Guidelines | Enterprise-Scale design principles and architecture guidelines for Azure. | Complete (January, 2020)| -| Automated build/test for code and deployment artifact for community contribution | Validate and test deployment artifact in test engineering Tenant to ensure quality and end to end deployment. | Complete (March, 2020) | -| Contoso Scope and Design | Prescriptive first-party reference implementation for the Enterprise-Scale architecture guidelines. Real-world example of applying Enterprise-Scale design principles to make contextualized decisions across all 8 design areas and define their target state. | Complete (March, 2020) | -| Contoso Reference Implementation | End to end reference implementation to supplement Architecture and Design recommendations. | Complete (April, 2020) | -| Publish Enterprise-Scale GitHub Action in Actions marketplace | This enables Resource discovery, deployments and operationalize IaC. | Complete (June, 2020) | -| Azure DevOps Support | Provide ability to operate AzOps within Azure DevOps with Azure Pipelines. | Complete (August, 2020) | -| Additional reference implementations | Prescriptive first-party reference implementation for the Enterprise-Scale architecture for different enterprise scenarios and size | Complete (October, 2020) | -| Data governance and analytics | Provide ability to deploy data landing zones and governance see [Enterprise Scale Analytics and AI](https://aka.ms/adopt/datamanagement.). | Planned (August 2021) | -| Workload Specific landing zones in Enterprise-Scale | AKS, WVD, SAP, HPC
(Seeking community Contribution) | Planned | -| Hybrid Management in Enterprise-Scale landing zones | Azure Arc | Planned | -| Support for N regions | ES Reference Implementations (Contoso, Adventure Works) | January, 2021 | -| Support for connecting N landing zones | ES Reference Implementations (Contoso, Adventure Works) | January, 2021 | +Please refer to [Roadmap](https://github.com/Azure/Enterprise-Scale/wiki/ALZ-Roadmap) diff --git a/docs/EnterpriseScale-Setup-aad-permissions.md b/docs/EnterpriseScale-Setup-aad-permissions.md index b63327d10c..d6f81da1a8 100644 --- a/docs/EnterpriseScale-Setup-aad-permissions.md +++ b/docs/EnterpriseScale-Setup-aad-permissions.md @@ -1,67 +1,3 @@ -# Configure Azure Active Directory permissions for Service Principal +# This page has moved to our Wiki -This article will guide you through the process to add your AzOps service principal to the Azure Active Directory [Directory Readers](https://docs.microsoft.com/en-us/azure/active-directory/users-groups-roles/directory-assign-admin-roles) role. - -> Note: The steps below requires you to use an identity that is local to the Azure AD, and **_not_** Guest user account due to known restrictions. - -The service principal used by the Enterprise-Scale reference implementation requires Azure AD directory reader permissions to be able to discover Azure role assignments. These permissions are used to enrich data around the role assignments with additional Azure AD context such as ObjectType and Azure AD Object DisplayName. - -## Add service principal to directory role via Azure Portal (Option 1) - -1.1 Sign in to the Azure portal or the Azure Active Directory admin center as a Global Administrator. If you are using Azure AD Privileged Identity Management, activate your Global Administrator role assignment. - -1.2 Open Azure Active Directory. - -1.3 Under _Manage_ > _Roles and administrators_, select _Directory readers_. -![alt](./media/aad-rolesandadministrators.png) - -1.4 Under _Manage_ > _Assignments_ > _Add assignments_, find for and select your AzOps service principal and finally add it to the directory role. - -![alt](./media/directory-reader.png) - -> Note: In case you are using Azure AD Privileged Identity management, ensure you add the service principal to the role with a permanent assignment. - -## Add service principal to directory role with Azure AD PowerShell (Option 2) - -Ensure that you have the [AzureAD PowerShell module installed on your machine](https://docs.microsoft.com/en-us/powershell/module/azuread/?view=azureadps-2.0) and that you have connected to Azure AD with the [Connect-AzureAD](https://docs.microsoft.com/en-us/powershell/module/azuread/connect-azuread?view=azureadps-2.0) cmdlet. - - -````powershell -#Param -- Default is AZOps -$ADServicePrincipal = "AZOps" - -#verify if AzureAD module is installed and running a minimum version, if not install with the latest version. -if ((Get-InstalledModule -Name "AzureAD" -MinimumVersion 2.0.2.130 ` -ErrorAction SilentlyContinue) -eq $null) { - - Write-Host "AzureAD Module does not exist" -ForegroundColor Yellow - Install-Module -Name AzureAD -Force - Import-Module -Name AzureAD - Connect-AzureAD #sign in to Azure from Powershell, this will redirect you to a webbrowser for authentication, if required - -} -else { - Write-Host "AzureAD Module exists with minimum version" -ForegroundColor Yellow - Import-Module -Name AzureAD - Connect-AzureAD #sign in to Azure from Powershell, this will redirect you to a webbrowser for authentication, if required -} - -#Verify Service Principal and if not pick a new one. -if (!(Get-AzureADServicePrincipal -Filter "DisplayName eq '$ADServicePrincipal'")) { - Write-Host "ServicePrincipal doesn't exist or is not AZOps" -ForegroundColor Red - break -} -else { - Write-Host "$ADServicePrincipal exist" -ForegroundColor Green - $ServicePrincipal = Get-AzureADServicePrincipal -Filter "DisplayName eq '$ADServicePrincipal'" - #Get Azure AD Directory Role - $DirectoryRole = Get-AzureADDirectoryRole -Filter "DisplayName eq 'Directory Readers'" - #Add service principal to Directory Role - Add-AzureADDirectoryRoleMember -ObjectId $DirectoryRole.ObjectId -RefObjectId $ServicePrincipal.ObjectId -} -```` - -Please note, it may take up to 15-30 minutes for permission to propagate in Azure AD. - -## Next steps - -Please proceed with [deploying reference implementation](./EnterpriseScale-Deploy-reference-implentations.md). +Please refer to [Configure Azure Active Directory permissions for Service Principal](https://github.com/Azure/Enterprise-Scale/wiki/ALZ-Setup-aad-permissions) diff --git a/docs/EnterpriseScale-Setup-azure.md b/docs/EnterpriseScale-Setup-azure.md index 68acad5734..060e36515c 100644 --- a/docs/EnterpriseScale-Setup-azure.md +++ b/docs/EnterpriseScale-Setup-azure.md @@ -1,74 +1,3 @@ -# Configure Azure permissions for ARM tenant deployments +# This page has moved to our Wiki -This article will guide you through the process of configuring permissions in your Azure environment to enable ARM tenant level deployments. - -> Note: The steps below require you to use an identity that is local to the Azure AD, and **_not_** Guest user account due to known restrictions. - -Enterprise-Scale reference implementation requires permission at tenant root scope "/" to be able to configure Management Group and create/move subscription. In order to grant permission at tenant root scope "/", users in "AAD Global Administrators" group can temporarily elevate access, to manage all Azure resources in the directory. - -Once the User Access Administrator (UAA) role is enabled, a UAA can grant **_other users and service principals_** within organization to deploy/manage Enterprise-Scale reference implementation by granting "Owner" permission at tenant root scope "/". - -Once permission is granted to other **users and service principals**, you can safely disable "User Access Administrator" permission for the "AAD Global Administrator" users. For more information please follow this article [elevated account permissions](https://docs.microsoft.com/azure/role-based-access-control/elevate-access-global-admin) - -## 1. Elevate Access to manage Azure resources in the directory - -1.1 Sign in to the Azure portal or the Azure Active Directory admin center as a Global Administrator. If you are using Azure AD Privileged Identity Management, activate your Global Administrator role assignment. - -1.2 Open Azure Active Directory. - -1.3 Under _Manage_, select _Properties_. -![alt](https://docs.microsoft.com/azure/role-based-access-control/media/elevate-access-global-admin/azure-active-directory-properties.png) - -1.4 Under _Access management for Azure resources_, set the toggle to Yes. - -![alt](https://docs.microsoft.com/azure/role-based-access-control/media/elevate-access-global-admin/aad-properties-global-admin-setting.png) - -## 2. Grant Access to User and/or Service principal at root scope "/" to deploy Enterprise-Scale reference implementation - -Please ensure you are logged in as a user with UAA role enabled in AAD tenant and logged in user is not a guest user. - -Bash - -````bash -#sign into AZ CLI, this will redirect you to a webbrowser for authentication, if required -az login - -#if you do not want to use a web browser you can use the following bash -read -sp "Azure password: " AZ_PASS && echo && az login -u -p $AZ_PASS - -#assign Owner role at Tenant root scope ("/") as a User Access Administrator to current user (gets object Id of the current user (az login)) -az role assignment create --scope '/' --role 'Owner' --assignee-object-id $(az ad signed-in-user show --query id --output tsv) --assignee-principal-type User - -#(optional) assign Owner role at Tenant root scope ("/") as a User Access Administrator to service principal (set spn_displayname to your service principal displayname) -spn_displayname='' -az role assignment create --scope '/' --role 'Owner' --assignee-object-id $(az ad sp list --display-name $spn_displayname --query '[].{objectId:objectId}' -o tsv) --assignee-principal-type ServicePrincipal -```` - -PowerShell - -````powershell -#sign in to Azure from Powershell, this will redirect you to a webbrowser for authentication, if required -Connect-AzAccount - -#get object Id of the current user (that is used above) -$user = Get-AzADUser -UserPrincipalName (Get-AzContext).Account - -#assign Owner role at Tenant root scope ("/") as a User Access Administrator to current user -New-AzRoleAssignment -Scope '/' -RoleDefinitionName 'Owner' -ObjectId $user.Id - -#(optional) assign Owner role at Tenant root scope ("/") as a User Access Administrator to service principal (set $spndisplayname to your service principal displayname) -$spndisplayname = "" -$spn = (Get-AzADServicePrincipal -DisplayName $spndisplayname).id -New-AzRoleAssignment -Scope '/' -RoleDefinitionName 'Owner' -ObjectId $spn -```` - -Please note, it may take up to 15-30 minutes for permission to propagate at tenant root scope. It is highly recommended that you log out and log back in. - -### Creating a scoped role assignment - -The Owner privileged root tenant scope *is required* in the deployment of the [Reference implementation](EnterpriseScale-Deploy-reference-implentations.md). However post deployment, and as your use of Enterprise Scale matures, you are able to limit the scope of the Service principal roleAssignments to a subsection of the Management Group hierarchy. -Eg. `"/providers/Microsoft.Management/managementGroups/YourMgGroup"`. - -## Next steps - -Please proceed with [deploying reference implementation](./EnterpriseScale-Deploy-reference-implentations.md). +Please refer to [Configure Azure permissions for ARM tenant deployments](https://github.com/Azure/Enterprise-Scale/wiki/ALZ-Setup-azure) diff --git a/docs/reference/Readme.md b/docs/reference/Readme.md index f1f253b5a5..80f20bd0e0 100644 --- a/docs/reference/Readme.md +++ b/docs/reference/Readme.md @@ -16,7 +16,7 @@ A policy will continuously check if a Virtual WAN VHub already exist in "Connect For all Azure Virtual WAN VHubs, Policies will ensure that Azure Firewall is deployed and linked to the existing global Azure Firewall Policy as well as the creation of a regional Firewall policy, if needed. -An Azure Policy will also deploy default NSGs and UDRs in Landing Zones and, while NSG will be linked to all subnets, UDR will only be linked to VNet injected PaaS services subnets. The Azure Policy will ensure that the right NSG and UDR rules are configured to allow control plane traffic for VNet injected services to continue to work but only for those Azure PaaS services that have been approved as per the [Service Enablement Framework](https://docs.microsoft.com/en-us/azure/cloud-adoption-framework/ready/enterprise-scale/security-governance-and-compliance#whitelist-the-service-framework) described in this document. This is required as, when landing zone VNets get connected to Virtual WAN VHub, they will get the default route (0.0.0.0/0) configured to point to their regional Azure Firewall, hence UDR and NSG rules are required to protect and manage control plane traffic for VNet injected PaaS services (such as SQL MI). +An Azure Policy will also deploy default NSGs and UDRs in Landing Zones and, while NSG will be linked to all subnets, UDR will only be linked to VNet injected PaaS services subnets. The Azure Policy will ensure that the right NSG and UDR rules are configured to allow control plane traffic for VNet injected services to continue to work but only for those Azure PaaS services that have been approved as per the [Service Enablement Framework](https://docs.microsoft.com/azure/cloud-adoption-framework/ready/enterprise-scale/security-governance-and-compliance#whitelist-the-service-framework) described in this document. This is required as, when landing zone VNets get connected to Virtual WAN VHub, they will get the default route (0.0.0.0/0) configured to point to their regional Azure Firewall, hence UDR and NSG rules are required to protect and manage control plane traffic for VNet injected PaaS services (such as SQL MI). For cross-premises connectivity, Policy will ensure that ExpressRoute and/or VPN gateways are deployed (as required by the regional VHub), and it will connect the VHub to on-premises using ExpressRoute (by taking the ExpressRoute Resource ID and authorization key as parameters). In case of VPN, Contoso can decide if they use their existing SD-WAN solution to automate the connectivity from branch offices into Azure via S2S VPN, or alternatively, Contoso can manually configure the CPE devices on the branch offices and then let Azure Policy to configure the VPN sites in Azure Virtual WAN. As Contoso is rolling out a SD-WAN solution to manage the connectivity of all their branches around the globe, their preference is to use the SD-WAN solution, which is a solution certified with Azure Virtual WAN, to connect all their branches to Azure. diff --git a/docs/reference/adventureworks/README.md b/docs/reference/adventureworks/README.md index 5155b0afce..2384161038 100644 --- a/docs/reference/adventureworks/README.md +++ b/docs/reference/adventureworks/README.md @@ -1,12 +1,12 @@ | ARM Template | Scale without refactoring | |:--------------|:--------------| -| [![Deploy To Azure](https://docs.microsoft.com/en-us/azure/templates/media/deploy-to-azure.svg)](https://portal.azure.com/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2FeslzArm%2FeslzArm.json/uiFormDefinitionUri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2FeslzArm%2Feslz-portal.json) | Yes | +| [![Deploy To Azure](https://docs.microsoft.com/azure/templates/media/deploy-to-azure.svg)](https://portal.azure.com/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2FeslzArm%2FeslzArm.json/uiFormDefinitionUri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2FeslzArm%2Feslz-portal.json) | Yes | # Deploy Enterprise-Scale with hub and spoke architecture The Enterprise-Scale architecture is modular by design and allow organizations to start with foundational landing zones that support their application portfolios and add hybrid connectivity with ExpressRoute or VPN when required. Alternatively, organizations can start with an Enterprise-Scale architecture based on the traditional hub and spoke network topology if customers require hybrid connectivity to on-premises locations from the beginning. -A hub and spoke network topology allows you to create a central Hub VNet that contains shared networking components (such as Azure Firewall, ExpressRoute and VPN Gateways) that can then be used by spoke VNets, connected to the Hub VNet via VNET Peering, to centralize connectivity in your environment. Gateway transit in VNet peering allows spokes to have connectivity to/from on-premises via ExpressRoute or VPN, and also, [transitive connectivity](https://azure.microsoft.com/en-us/blog/create-a-transit-vnet-using-vnet-peering/) across spokes can be implemented by deploying User Defined Routes (UDR) on the spokes and using Azure Firewall or an NVA in the hub as the transit resource. Hub and spoke network design considerations & recommendations can be found [here](https://docs.microsoft.com/en-us/azure/cloud-adoption-framework/ready/azure-best-practices/traditional-azure-networking-topology). +A hub and spoke network topology allows you to create a central Hub VNet that contains shared networking components (such as Azure Firewall, ExpressRoute and VPN Gateways) that can then be used by spoke VNets, connected to the Hub VNet via VNET Peering, to centralize connectivity in your environment. Gateway transit in VNet peering allows spokes to have connectivity to/from on-premises via ExpressRoute or VPN, and also, [transitive connectivity](https://azure.microsoft.com/blog/create-a-transit-vnet-using-vnet-peering/) across spokes can be implemented by deploying User Defined Routes (UDR) on the spokes and using Azure Firewall or an NVA in the hub as the transit resource. Hub and spoke network design considerations & recommendations can be found [here](https://docs.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/traditional-azure-networking-topology). ![Hub & Spoke Network Topology](./media/hub-and-spoke-topology.png) diff --git a/docs/reference/contoso/Readme.md b/docs/reference/contoso/Readme.md index e437f2f07a..87a2aeb971 100644 --- a/docs/reference/contoso/Readme.md +++ b/docs/reference/contoso/Readme.md @@ -1,7 +1,7 @@ | ARM Template | Scale without refactoring | |:--------------|:--------------| -|[![Deploy To Azure](https://docs.microsoft.com/en-us/azure/templates/media/deploy-to-azure.svg)](https://portal.azure.com/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2FeslzArm%2FeslzArm.json/uiFormDefinitionUri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2FeslzArm%2Feslz-portal.json) | Yes | +|[![Deploy To Azure](https://docs.microsoft.com/azure/templates/media/deploy-to-azure.svg)](https://portal.azure.com/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2FeslzArm%2FeslzArm.json/uiFormDefinitionUri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2FeslzArm%2Feslz-portal.json) | Yes | # Deploy Enterprise-Scale with Azure VWAN diff --git a/docs/reference/treyresearch/README.md b/docs/reference/treyresearch/README.md index 1a843a62f8..7e3b0a9129 100644 --- a/docs/reference/treyresearch/README.md +++ b/docs/reference/treyresearch/README.md @@ -1,6 +1,6 @@ | ARM Template | Scale without refactoring | |:--------------|:--------------| -| [![Deploy To Azure](https://docs.microsoft.com/en-us/azure/templates/media/deploy-to-azure.svg)](https://portal.azure.com/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2FeslzArm%2FeslzArm.json/uiFormDefinitionUri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2FeslzArm%2Feslz-portal.json) | Yes | +| [![Deploy To Azure](https://docs.microsoft.com/azure/templates/media/deploy-to-azure.svg)](https://portal.azure.com/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2FeslzArm%2FeslzArm.json/uiFormDefinitionUri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2FeslzArm%2Feslz-portal.json) | Yes | # Deploy Enterprise-scale for small enterprises @@ -22,15 +22,15 @@ If the business requirements change over time, the architecture allows for creat ## Pre-requisites -To deploy this ARM template, your user/service principal must have Owner permission at the Azure Active Directory Tenant root. See the following [instructions](https://docs.microsoft.com/en-us/azure/role-based-access-control/elevate-access-global-admin) on how to grant access before you proceed. +To deploy this ARM template, your user/service principal must have Owner permission at the Azure Active Directory Tenant root. See the following [instructions](https://docs.microsoft.com/azure/role-based-access-control/elevate-access-global-admin) on how to grant access before you proceed. ## Optional pre-requisites The deployment experience in Azure portal allows you to bring in an existing (preferably empty) subscription dedicated to host your Platform (Management, Connectivity and Identity) resources. It also allows you to bring existing subscriptions that can be used as the initial landing zones for your applications. -To learn how to create new subscriptions programmatically, please visit [Microsoft Docs](https://docs.microsoft.com/en-us/azure/cost-management-billing/manage/programmatically-create-subscription). +To learn how to create new subscriptions programmatically, please visit [Microsoft Docs](https://docs.microsoft.com/azure/cost-management-billing/manage/programmatically-create-subscription). -To learn how to create new subscriptions using the Azure portal, please visit [Microsoft Docs](https://azure.microsoft.com/en-us/blog/create-enterprise-subscription-experience-in-azure-portal-public-preview/). +To learn how to create new subscriptions using the Azure portal, please visit [Microsoft Docs](https://azure.microsoft.com/blog/create-enterprise-subscription-experience-in-azure-portal-public-preview/). ## How to deploy this reference implementation @@ -47,21 +47,21 @@ By default, all recommendations are enabled. You must explicitly disable them if - A scalable Management Group hierarchy aligned to core platform capabilities, allowing you to operationalize at scale using centrally managed Azure RBAC and Azure Policy where platform and workloads have clear separation. - An Azure subscription dedicated for management, connectivity, and identity. This subscription hosts core platform capabilities such as: - - A Log Analytics workspace and an Automation account. + - A Log Analytics workspace and an Automation account. - Azure Sentinel. - - A hub virtual network - - VPN Gateway (optional - deployment across Availability Zones) + - A hub virtual network + - VPN Gateway (optional - deployment across Availability Zones) - ExpressRoute Gateway (optional - deployment across Availability Zones) - - Azure Firewall (optional - deployment across Availability Zones) + - Azure Firewall (optional - deployment across Availability Zones) - Landing Zone Management Group for **corp** connected applications that require connectivity to on-premises, to other landing zones or to the internet via shared services provided in the hub virtual network. - This is where you will create your subscriptions that will host your corp-connected workloads. - Landing Zone Management Group for **online** applications that will be internet-facing, where a virtual network is optional and hybrid connectivity is not required. - This is where you will create your Subscriptions that will host your online workloads. - Azure Policies that will enable autonomy for the platform and the landing zones: - The following Azure Policies are applied at the root of the Enterprise Scale Management Group hierarchy enabling core platform capabilities at scale: - - Azure Security monitoring - - Azure Security Center (Azure Defender OFF (free) and Azure Defender ON) - - Diagnostics settings for Activity Logs, VMs, and PaaS resources sent to Log Analytics + - Azure Security monitoring + - Azure Security Center (Azure Defender OFF (free) and Azure Defender ON) + - Diagnostics settings for Activity Logs, VMs, and PaaS resources sent to Log Analytics - On the other hand, Azure Policies that will apply to all your landing zones. That includes Online, Corp and additional Landing Zone's types you may add in the future: - Enforce VM in-guest monitoring (Windows & Linux) - Enforce Backup for all virtual machines (Windows & Linux) by deploying a recovery services vault in the same location and resource group as the virtual machine @@ -73,17 +73,17 @@ By default, all recommendations are enabled. You must explicitly disable them if - Enforce auditing for Azure SQL - Enforce secure access (HTTPS) to storage accounts -![Trey Research](media/es-lite.png) +![Trey Research](./media/es-lite.png) ## Next steps -### From an application perspective: +### From an application perspective #### Configure security roles for your Azure resources Assign Azure RBAC permissions to the groups/users who should use the landing zones (subscriptions) so they can start deploying their workloads. -Azure role-based access control (Azure RBAC) is a system that provides fine-grained access management of Azure resources. Using Azure RBAC, you can segregate your team's duties and grant only the amount of access to users that they need to perform their jobs. See more about security roles at [Microsoft Docs](https://docs.microsoft.com/en-us/azure/role-based-access-control/). +Azure role-based access control (Azure RBAC) is a system that provides fine-grained access management of Azure resources. Using Azure RBAC, you can segregate your team's duties and grant only the amount of access to users that they need to perform their jobs. See more about security roles at [Microsoft Docs](https://docs.microsoft.com/azure/role-based-access-control/). #### Manage your Landing Zones diff --git a/docs/reference/treyresearch/armTemplates/auxiliary/logAnalyticsSolutions.json b/docs/reference/treyresearch/armTemplates/auxiliary/logAnalyticsSolutions.json index 22fa5baa14..1566161abb 100644 --- a/docs/reference/treyresearch/armTemplates/auxiliary/logAnalyticsSolutions.json +++ b/docs/reference/treyresearch/armTemplates/auxiliary/logAnalyticsSolutions.json @@ -48,14 +48,6 @@ ], "defaultValue": "Yes" }, - "enableActivityLog": { - "type": "string", - "allowedValues": [ - "Yes", - "No" - ], - "defaultValue": "Yes" - }, "enableAntiMalware": { "type": "string", "allowedValues": [ @@ -108,10 +100,6 @@ "name": "[concat('Updates', '(', parameters('workspaceName'), ')')]", "marketplaceName": "Updates" }, - "azureActivity": { - "name": "[concat('AzureActivity', '(', parameters('workspaceName'), ')')]", - "marketplaceName": "AzureActivity" - }, "sqlAssessment": { "name": "[concat('SQLAssessment', '(', parameters('workspaceName'), ')')]", "marketplaceName": "SQLAssessment" @@ -180,22 +168,6 @@ "publisher": "Microsoft" } }, - { - "condition": "[equals(parameters('enableActivityLog'), 'Yes')]", - "apiVersion": "2015-11-01-preview", - "type": "Microsoft.OperationsManagement/solutions", - "name": "[variables('solutions').azureActivity.name]", - "location": "[parameters('workspaceRegion')]", - "properties": { - "workspaceResourceId": "[variables('laResourceId')]" - }, - "plan": { - "name": "[variables('solutions').azureActivity.name]", - "product": "[concat('OMSGallery/', variables('solutions').azureActivity.marketplaceName)]", - "promotionCode": "", - "publisher": "Microsoft" - } - }, { "condition": "[equals(parameters('enableChangeTracking'), 'Yes')]", "apiVersion": "2015-11-01-preview", diff --git a/docs/reference/treyresearch/armTemplates/es-lite.json b/docs/reference/treyresearch/armTemplates/es-lite.json index db561b3982..4a197ab0d9 100644 --- a/docs/reference/treyresearch/armTemplates/es-lite.json +++ b/docs/reference/treyresearch/armTemplates/es-lite.json @@ -170,14 +170,6 @@ ], "defaultValue": "Yes" }, - "enableActivityLog": { - "type": "string", - "allowedValues": [ - "Yes", - "No" - ], - "defaultValue": "Yes" - }, "enableAntiMalware": { "type": "string", "allowedValues": [ @@ -559,7 +551,7 @@ } }, { - "condition": "[and(not(empty(parameters('platformSubscriptionId'))), or(or(or(or(or(equals(parameters('enableSecuritySolution'), 'Yes'), equals(parameters('enableAgentHealth'), 'Yes')), equals(parameters('enableChangeTracking'), 'Yes')), equals(parameters('enableUpdateMgmt'), 'Yes'), equals(parameters('enableActivityLog'), 'Yes')), equals(parameters('enableAntiMalware'), 'Yes'), equals(parameters('enableVmInsights'), 'Yes')), equals(parameters('enableServiceMap'), 'Yes'), equals(parameters('enableSqlAssessment'), 'Yes')))]", + "condition": "[and(not(empty(parameters('platformSubscriptionId'))), or(or(or(or(equals(parameters('enableSecuritySolution'), 'Yes'), equals(parameters('enableAgentHealth'), 'Yes')), equals(parameters('enableChangeTracking'), 'Yes')), equals(parameters('enableUpdateMgmt'), 'Yes')), equals(parameters('enableAntiMalware'), 'Yes'), equals(parameters('enableVmInsights'), 'Yes')), equals(parameters('enableServiceMap'), 'Yes'), equals(parameters('enableSqlAssessment'), 'Yes'))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2019-05-01", "subscriptionId": "[parameters('platformSubscriptionId')]", @@ -593,9 +585,6 @@ "enableUpdateMgmt": { "value": "[parameters('enableUpdateMgmt')]" }, - "enableActivityLog": { - "value": "[parameters('enableActivityLog')]" - }, "enableAntiMalware": { "value": "[parameters('enableAntiMalware')]" }, diff --git a/docs/reference/treyresearch/armTemplates/es-portal.json b/docs/reference/treyresearch/armTemplates/es-portal.json index c2305b1cc2..eb35638fa7 100644 --- a/docs/reference/treyresearch/armTemplates/es-portal.json +++ b/docs/reference/treyresearch/armTemplates/es-portal.json @@ -15,1277 +15,1256 @@ } ] }, - { - "name": "lzSettings", - "label": "Enterprise-Scale company prefix", - "subLabel": { - "preValidation": "Provide a company prefix for the management group structure that will be created.", - "postValidation": "Done" - }, - "bladeTitle": "Company prefix", - "elements": [ - { - "name": "infoBox0", - "type": "Microsoft.Common.InfoBox", - "visible": true, - "options": { - "icon": "Info", - "text": "Enterprise-Scale ARM deployment requires access at the tenant root (/) scope. Visit this link to ensure you have the appropriate RBAC permission to complete the deployment", - "uri": "https://docs.microsoft.com/azure/role-based-access-control/elevate-access-global-admin" - } + { + "name": "lzSettings", + "label": "Enterprise-Scale company prefix", + "subLabel": { + "preValidation": "Provide a company prefix for the management group structure that will be created.", + "postValidation": "Done" }, - { - "name": "textBlock0", - "type": "Microsoft.Common.TextBlock", - "visible": true, - "options": { - "text": "Enterprise-Scale will create the management group hierarchy under the Tenant Root Group with the prefix provided at this step.", - "link": { - "label": "Learn more", - "uri": "https://docs.microsoft.com/azure/cloud-adoption-framework/ready/enterprise-scale/management-group-and-subscription-organization" + "bladeTitle": "Company prefix", + "elements": [ + { + "name": "infoBox0", + "type": "Microsoft.Common.InfoBox", + "visible": true, + "options": { + "icon": "Info", + "text": "Enterprise-Scale ARM deployment requires access at the tenant root (/) scope. Visit this link to ensure you have the appropriate RBAC permission to complete the deployment", + "uri": "https://docs.microsoft.com/azure/role-based-access-control/elevate-access-global-admin" + } + }, + { + "name": "textBlock0", + "type": "Microsoft.Common.TextBlock", + "visible": true, + "options": { + "text": "Enterprise-Scale will create the management group hierarchy under the Tenant Root Group with the prefix provided at this step.", + "link": { + "label": "Learn more", + "uri": "https://docs.microsoft.com/azure/cloud-adoption-framework/ready/enterprise-scale/management-group-and-subscription-organization" + } + } + }, + { + "name": "esMgmtGroup", + "type": "Microsoft.Common.TextBox", + "label": "Management Group prefix", + "toolTip": "Provide a prefix (max 10 characters, unique at tenant-scope) for the Management Group hierarchy and other resources created as part of Enterprise-scale.", + "defaultValue": "", + "constraints": { + "required": true, + "regex": "^[a-z0-9A-Z-]{1,10}$", + "validationMessage": "The prefix must be 1-10 characters." } } - }, - { - "name": "esMgmtGroup", - "type": "Microsoft.Common.TextBox", - "label": "Management Group prefix", - "toolTip": "Provide a prefix (max 10 characters, unique at tenant-scope) for the Management Group hierarchy and other resources created as part of Enterprise-scale.", - "defaultValue": "", - "constraints": { - "required": true, - "regex": "^[a-z0-9A-Z-]{1,10}$", - "validationMessage": "The prefix must be 1-10 characters." - } - } - ] - }, - { - "name": "esGoalState", - "label": "Platform configuration", - "subLabel": { - "preValidation": "Select 'Yes' if goal state should be enforced during deployment. Select 'No' if you want to do it post deployment using Azure Policy.", - "postValidation": "Done" + ] }, - "bladeTitle": "lzGs", - "elements": [ - { - "name": "infoBox1", - "type": "Microsoft.Common.InfoBox", - "visible": true, - "options": { - "icon": "Info", - "text": "To enable platform management, security and governance, you must allocate a platform Subscription. Please note, this Subscription will be moved to the platform Management Group, and ARM will deploy the requisite settings. We recommend using a new Subscription with no existing resources.", - "uri": "https://github.com/Azure/Enterprise-Scale/blob/main/docs/reference/Readme.md" - } + { + "name": "esGoalState", + "label": "Platform configuration", + "subLabel": { + "preValidation": "Select 'Yes' if goal state should be enforced during deployment. Select 'No' if you want to do it post deployment using Azure Policy.", + "postValidation": "Done" }, - { - "name": "esLogAnalytics", - "type": "Microsoft.Common.OptionsGroup", - "label": "Deploy Log Analytics workspace.", - "defaultValue": "Yes (recommended)", - "toolTip": "If 'Yes' is selected when also adding a subscription for management, ARM will deploy resources and enable them for continuous compliance.", - "constraints": { - "allowedValues": [ - { - "label": "Yes (recommended)", - "value": "Yes" - }, - { - "label": "No", - "value": "No" - } - ] + "bladeTitle": "lzGs", + "elements": [ + { + "name": "infoBox1", + "type": "Microsoft.Common.InfoBox", + "visible": true, + "options": { + "icon": "Info", + "text": "To enable platform management, security and governance, you must allocate a platform Subscription. Please note, this Subscription will be moved to the platform Management Group, and ARM will deploy the requisite settings. We recommend using a new Subscription with no existing resources.", + "uri": "https://github.com/Azure/Enterprise-Scale/blob/main/docs/reference/Readme.md" + } }, - "visible": true - }, - { - "name": "esLogRetention", - "type": "Microsoft.Common.Slider", - "min": 30, - "max": 730, - "label": "Log Analytics Data Retention (days)", - "subLabel": "Days", - "defaultValue": 30, - "showStepMarkers": false, - "toolTip": "Select retention days for Azure logs. Default is 30 days.", - "constraints": { - "required": false + { + "name": "esLogAnalytics", + "type": "Microsoft.Common.OptionsGroup", + "label": "Deploy Log Analytics workspace.", + "defaultValue": "Yes (recommended)", + "toolTip": "If 'Yes' is selected when also adding a subscription for management, ARM will deploy resources and enable them for continuous compliance.", + "constraints": { + "allowedValues": [ + { + "label": "Yes (recommended)", + "value": "Yes" + }, + { + "label": "No", + "value": "No" + } + ] + }, + "visible": true }, - "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" - }, - { - "name": "mgmtSubsApi", - "type": "Microsoft.Solutions.ArmApiControl", - "request": { - "method": "GET", - "path": "subscriptions?api-version=2020-01-01" - } - }, - { - "name": "esMgmtSub", - "type": "Microsoft.Common.DropDown", - "label": "Platform subscription (required)", - "toolTip": "", - "multiselect": false, - "selectAll": true, - "filter": true, - "filterPlaceholder": "Filter items ...", - "multiLine": true, - "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]", - "constraints": { - "allowedValues": "[map(steps('esGoalState').mgmtSubsApi.value, (sub) => parse(concat('{\"label\":\"', sub.displayName, '\",\"description\":\"', sub.subscriptionId, '\",\"value\":\"', toLower(sub.subscriptionId), '\"}')) )]", - "required": true - } - }, - { - "name": "textBlock1", - "type": "Microsoft.Common.TextBlock", - "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]", - "options": { - "text": "Select which Azure Monitor solutions you will enable for your Log Analytics workspace", - "link": { - "label": "Learn more", - "uri": "https://docs.microsoft.com/azure/azure-monitor/insights/solutions" + { + "name": "esLogRetention", + "type": "Microsoft.Common.Slider", + "min": 30, + "max": 730, + "label": "Log Analytics Data Retention (days)", + "subLabel": "Days", + "defaultValue": 30, + "showStepMarkers": false, + "toolTip": "Select retention days for Azure logs. Default is 30 days.", + "constraints": { + "required": false + }, + "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" + }, + { + "name": "mgmtSubsApi", + "type": "Microsoft.Solutions.ArmApiControl", + "request": { + "method": "GET", + "path": "subscriptions?api-version=2020-01-01" } - } - }, - { - "name": "esAgentSolution", - "type": "Microsoft.Common.OptionsGroup", - "label": "Deploy Agent Health solution", - "defaultValue": "Yes (recommended)", - "toolTip": "If 'Yes' is selected when also adding a subscription for management, ARM will deploy resources and enable them for continous compliance", - "constraints": { - "allowedValues": [ - { - "label": "Yes (recommended)", - "value": "Yes" - }, - { - "label": "No", - "value": "No" - } - ] }, - "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" - }, - { - "name": "esChangeTracking", - "type": "Microsoft.Common.OptionsGroup", - "label": "Deploy Change Tracking solution", - "defaultValue": "Yes (recommended)", - "toolTip": "If 'Yes' is selected when also adding a subscription for management, ARM will deploy resources and enable them for continous compliance", - "constraints": { - "allowedValues": [ - { - "label": "Yes (recommended)", - "value": "Yes" - }, - { - "label": "No", - "value": "No" - } - ] + { + "name": "esMgmtSub", + "type": "Microsoft.Common.DropDown", + "label": "Platform subscription (required)", + "toolTip": "", + "multiselect": false, + "selectAll": true, + "filter": true, + "filterPlaceholder": "Filter items ...", + "multiLine": true, + "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]", + "constraints": { + "allowedValues": "[map(steps('esGoalState').mgmtSubsApi.value, (sub) => parse(concat('{\"label\":\"', sub.displayName, '\",\"description\":\"', sub.subscriptionId, '\",\"value\":\"', toLower(sub.subscriptionId), '\"}')) )]", + "required": true + } }, - "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" - }, - { - "name": "esUpdateMgmt", - "type": "Microsoft.Common.OptionsGroup", - "label": "Deploy Update Management solution", - "defaultValue": "Yes (recommended)", - "toolTip": "If 'Yes' is selected when also adding a subscription for management, ARM will deploy resources and enable them for continous compliance", - "constraints": { - "allowedValues": [ - { - "label": "Yes (recommended)", - "value": "Yes" - }, - { - "label": "No", - "value": "No" + { + "name": "textBlock1", + "type": "Microsoft.Common.TextBlock", + "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]", + "options": { + "text": "Select which Azure Monitor solutions you will enable for your Log Analytics workspace", + "link": { + "label": "Learn more", + "uri": "https://docs.microsoft.com/azure/azure-monitor/insights/solutions" } - ] + } }, - "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" - }, - { - "name": "esActivityLog", - "type": "Microsoft.Common.OptionsGroup", - "label": "Deploy Activity Log solution", - "defaultValue": "Yes (recommended)", - "toolTip": "If 'Yes' is selected when also adding a subscription for management, ARM will deploy resources and enable them for continous compliance", - "constraints": { - "allowedValues": [ - { - "label": "Yes (recommended)", - "value": "Yes" - }, - { - "label": "No", - "value": "No" - } - ] + { + "name": "esAgentSolution", + "type": "Microsoft.Common.OptionsGroup", + "label": "Deploy Agent Health solution", + "defaultValue": "Yes (recommended)", + "toolTip": "If 'Yes' is selected when also adding a subscription for management, ARM will deploy resources and enable them for continous compliance", + "constraints": { + "allowedValues": [ + { + "label": "Yes (recommended)", + "value": "Yes" + }, + { + "label": "No", + "value": "No" + } + ] + }, + "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" }, - "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" - }, - { - "name": "esVmInsights", - "type": "Microsoft.Common.OptionsGroup", - "label": "Deploy VM Insights solution", - "defaultValue": "Yes (recommended)", - "toolTip": "If 'Yes' is selected when also adding a subscription for management, ARM will deploy resources and enable them for continous compliance", - "constraints": { - "allowedValues": [ - { - "label": "Yes (recommended)", - "value": "Yes" - }, - { - "label": "No", - "value": "No" - } - ] + { + "name": "esChangeTracking", + "type": "Microsoft.Common.OptionsGroup", + "label": "Deploy Change Tracking solution", + "defaultValue": "Yes (recommended)", + "toolTip": "If 'Yes' is selected when also adding a subscription for management, ARM will deploy resources and enable them for continous compliance", + "constraints": { + "allowedValues": [ + { + "label": "Yes (recommended)", + "value": "Yes" + }, + { + "label": "No", + "value": "No" + } + ] + }, + "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" }, - "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" - }, - { - "name": "esAntiMalware", - "type": "Microsoft.Common.OptionsGroup", - "label": "Deploy Antimalware solution", - "defaultValue": "Yes (recommended)", - "toolTip": "If 'Yes' is selected when also adding a subscription for management, ARM will deploy resources and enable them for continous compliance", - "constraints": { - "allowedValues": [ - { - "label": "Yes (recommended)", - "value": "Yes" - }, - { - "label": "No", - "value": "No" - } - ] + { + "name": "esUpdateMgmt", + "type": "Microsoft.Common.OptionsGroup", + "label": "Deploy Update Management solution", + "defaultValue": "Yes (recommended)", + "toolTip": "If 'Yes' is selected when also adding a subscription for management, ARM will deploy resources and enable them for continous compliance", + "constraints": { + "allowedValues": [ + { + "label": "Yes (recommended)", + "value": "Yes" + }, + { + "label": "No", + "value": "No" + } + ] + }, + "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" }, - "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" - }, - { - "name": "esServiceMap", - "type": "Microsoft.Common.OptionsGroup", - "label": "Deploy Service Map solution", - "defaultValue": "Yes (recommended)", - "toolTip": "If 'Yes' is selected when also adding a subscription for management, ARM will deploy resources and enable them for continous compliance", - "constraints": { - "allowedValues": [ - { - "label": "Yes (recommended)", - "value": "Yes" - }, - { - "label": "No", - "value": "No" - } - ] + { + "name": "esVmInsights", + "type": "Microsoft.Common.OptionsGroup", + "label": "Deploy VM Insights solution", + "defaultValue": "Yes (recommended)", + "toolTip": "If 'Yes' is selected when also adding a subscription for management, ARM will deploy resources and enable them for continous compliance", + "constraints": { + "allowedValues": [ + { + "label": "Yes (recommended)", + "value": "Yes" + }, + { + "label": "No", + "value": "No" + } + ] + }, + "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" }, - "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" - }, - { - "name": "esSqlAssessment", - "type": "Microsoft.Common.OptionsGroup", - "label": "Deploy SQL Assessment solution", - "defaultValue": "Yes (recommended)", - "toolTip": "If 'Yes' is selected when also adding a subscription for management, ARM will deploy resources and enable them for continous compliance", - "constraints": { - "allowedValues": [ - { - "label": "Yes (recommended)", - "value": "Yes" - }, - { - "label": "No", - "value": "No" - } - ] + { + "name": "esAntiMalware", + "type": "Microsoft.Common.OptionsGroup", + "label": "Deploy Antimalware solution", + "defaultValue": "Yes (recommended)", + "toolTip": "If 'Yes' is selected when also adding a subscription for management, ARM will deploy resources and enable them for continous compliance", + "constraints": { + "allowedValues": [ + { + "label": "Yes (recommended)", + "value": "Yes" + }, + { + "label": "No", + "value": "No" + } + ] + }, + "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" }, - "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" - }, - { - "name": "textBlock0", - "type": "Microsoft.Common.TextBlock", - "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]", - "options": { - "text": "Select which Azure Security solutions you will enable.", - "link": { - "label": "Learn more", - "uri": "https://docs.microsoft.com/azure/security/fundamentals/overview" - } - } - }, - { - "name": "esAsc", - "type": "Microsoft.Common.OptionsGroup", - "label": "Deploy Azure Security Center and enable security monitoring for your platform and resources", - "defaultValue": "Yes, Azure Defender On (recommended)", - "toolTip": "If 'Yes' is selected when also adding a subscription for management, ARM will deploy resources and enable them for continous compliance", - "constraints": { - "allowedValues": [ - { - "label": "Yes, Azure Defender On (recommended)", - "value": "Standard" - }, - { - "label": "Yes, Azure Defender Off", - "value": "Free" - }, - { - "label": "No", - "value": "No" - } - ] + { + "name": "esServiceMap", + "type": "Microsoft.Common.OptionsGroup", + "label": "Deploy Service Map solution", + "defaultValue": "Yes (recommended)", + "toolTip": "If 'Yes' is selected when also adding a subscription for management, ARM will deploy resources and enable them for continous compliance", + "constraints": { + "allowedValues": [ + { + "label": "Yes (recommended)", + "value": "Yes" + }, + { + "label": "No", + "value": "No" + } + ] + }, + "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" }, - "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" - }, - { - "name": "esAscEmail", - "type": "Microsoft.Common.TextBox", - "label": "Azure Security Center Email Contact", - "toolTip": "Email address to get email notifications from Azure Security Center", - "visible": "[or(equals(steps('esGoalState').esAsc,'Standard'),equals(steps('esGoalState').esAsc,'Free'))]", - "defaultValue": "", - "constraints": { - "required": "[equals(steps('esGoalState').esAsc,'Yes')]", - "regex": "^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$", - "validationMessage": "Please provide a valid email address" - } - }, - { - "name": "esSecuritySolution", - "type": "Microsoft.Common.OptionsGroup", - "label": "Deploy Azure Sentinel", - "defaultValue": "No", - "toolTip": "If 'Yes' is selected when also adding a subscription for management, ARM will deploy resources and enable them for continous compliance", - "constraints": { - "allowedValues": [ - { - "label": "Yes", - "value": "Yes" - }, - { - "label": "No", - "value": "No" - } - ] + { + "name": "esSqlAssessment", + "type": "Microsoft.Common.OptionsGroup", + "label": "Deploy SQL Assessment solution", + "defaultValue": "Yes (recommended)", + "toolTip": "If 'Yes' is selected when also adding a subscription for management, ARM will deploy resources and enable them for continous compliance", + "constraints": { + "allowedValues": [ + { + "label": "Yes (recommended)", + "value": "Yes" + }, + { + "label": "No", + "value": "No" + } + ] + }, + "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" }, - "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" - } - ] - }, - { - "name": "esConnectivityGoalState", - "label": "Connectivity (Hub & Spoke)", - "subLabel": { - "preValidation": "Select 'Yes' if goal state should be enforced during deployment. Select 'No' if you want to do it post deployment using Azure Policy.", - "postValidation": "Done" - }, - "bladeTitle": "lzGs", - "elements": [ - { - "name": "infoBox1", - "type": "Microsoft.Common.InfoBox", - "visible": true, - "options": { - "icon": "Info", - "text": "Enterprise Scale allows you to enable hybrid connectivity with on premises using Hub & Spoke topology. Please note, all connectivity components required will be deployed to the Platform Subscription.", - "uri": "https://github.com/Azure/Enterprise-Scale/blob/main/docs/reference/Readme.md" - } - }, - { - "name": "esHub", - "type": "Microsoft.Common.OptionsGroup", - "label": "Deploy virtual hub", - "defaultValue": "Yes", - "toolTip": "If 'Yes' is selected, ARM will deploy a virtual network for hub", - "constraints": { - "allowedValues": [ - { - "label": "Yes", - "value": "Yes" - }, - { - "label": "No", - "value": "No" + { + "name": "textBlock0", + "type": "Microsoft.Common.TextBlock", + "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]", + "options": { + "text": "Select which Azure Security solutions you will enable.", + "link": { + "label": "Learn more", + "uri": "https://docs.microsoft.com/azure/security/fundamentals/overview" } - ] + } }, - "visible": true - }, - { - "name": "nwSubsApi", - "type": "Microsoft.Solutions.ArmApiControl", - "request": { - "method": "GET", - "path": "subscriptions?api-version=2020-01-01" - } - }, - { - "name": "esConnectivitySub", - "type": "Microsoft.Common.DropDown", - "label": "Platform subscription (required)", - "toolTip": "You did not provided a Platform Subscription yet. You must allocate one now. Please note, this Subscription will be moved to the platform Management Group, and ARM will deploy the first networking hub and requisite settings. We recommend using a new Subscription with no existing resources.", - "multiselect": false, - "selectAll": true, - "filter": true, - "filterPlaceholder": "Filter items ...", - "multiLine": true, - "defaultValue": "[if(not(empty(steps('esGoalState').esMgmtSub)),steps('esGoalState').esMgmtSub,'')]", - "visible": "[and(equals(steps('esConnectivityGoalState').esHub,'Yes'),empty(steps('esGoalState').esMgmtSub))]", - "constraints": { - "allowedValues": "[map(steps('esConnectivityGoalState').nwSubsApi.value, (sub) => parse(concat('{\"label\":\"', sub.displayName, '\",\"description\":\"', sub.subscriptionId, '\",\"value\":\"', toLower(sub.subscriptionId), '\"}')) )]", - "required": "[and(equals(steps('esConnectivityGoalState').esHub,'Yes'),empty(steps('esGoalState').esMgmtSub))]" - } - }, - { - "name": "esAddressHub", - "type": "Microsoft.Common.TextBox", - "label": "Address space (required for virtual network hub)", - "toolTip": "Provide address prefix in CIDR notation (e.g 10.100.0.0/16)", - "defaultValue": "10.100.0.0/16", - "visible": "[equals(steps('esConnectivityGoalState').esHub, 'Yes')]", - "constraints": { - "required": true, - "validationMessage": "The virtual hubs network's address space, specified as one address prefixes in CIDR notation (e.g. 192.168.1.0/24)" - } - }, - { - "name": "esLocationsApi", - "type": "Microsoft.Solutions.ArmApiControl", - "request": { - "method": "GET", - "path": "locations?api-version=2019-11-01" - } - }, - { - "name": "esNwLocation", - "type": "Microsoft.Common.DropDown", - "label": "Region for the first virtual network hub", - "filter": true, - "toolTip": "Select the target region for you connectivity deployment (requires you to provide a subscriptionId for connectivity)", - "constraints": { - "allowedValues": "[map(steps('esConnectivityGoalState').esLocationsApi.value, (item) => parse(concat('{\"label\":\"', item.displayName, '\",\"value\":\"', item.name, '\"}')))]", - "required": true + { + "name": "esAsc", + "type": "Microsoft.Common.OptionsGroup", + "label": "Deploy Azure Security Center and enable security monitoring for your platform and resources", + "defaultValue": "Yes, Azure Defender On (recommended)", + "toolTip": "If 'Yes' is selected when also adding a subscription for management, ARM will deploy resources and enable them for continous compliance", + "constraints": { + "allowedValues": [ + { + "label": "Yes, Azure Defender On (recommended)", + "value": "Standard" + }, + { + "label": "Yes, Azure Defender Off", + "value": "Free" + }, + { + "label": "No", + "value": "No" + } + ] + }, + "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" }, - "visible": "[equals(steps('esConnectivityGoalState').esHub, 'Yes')]" - }, - { - "name": "esDdoS", - "type": "Microsoft.Common.OptionsGroup", - "label": "Enable DDoS Protection Standard", - "defaultValue": "No", - "visible": "[equals(steps('esConnectivityGoalState').esHub,'Yes')]", - "toolTip": "If 'Yes' is selected when also adding a connectivity subscription, DDoS Protection Standard will be enabled.", - "constraints": { - "allowedValues": [ - { - "label": "Yes (recommended)", - "value": "Yes" - }, - { - "label": "No", - "value": "No" - } - ] - } - }, - { - "name": "textBlock0", - "type": "Microsoft.Common.TextBlock", - "visible": "[equals(steps('esConnectivityGoalState').esHub, 'Yes')]", - "options": { - "text": "To know more about Azure DDos protection pricing.", - "link": { - "label": "Azure DDoS Pricing", - "uri": "https://azure.microsoft.com/en-us/pricing/details/ddos-protection/" + { + "name": "esAscEmail", + "type": "Microsoft.Common.TextBox", + "label": "Azure Security Center Email Contact", + "toolTip": "Email address to get email notifications from Azure Security Center", + "visible": "[or(equals(steps('esGoalState').esAsc,'Standard'),equals(steps('esGoalState').esAsc,'Free'))]", + "defaultValue": "", + "constraints": { + "required": "[equals(steps('esGoalState').esAsc,'Yes')]", + "regex": "^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$", + "validationMessage": "Please provide a valid email address" } + }, + { + "name": "esSecuritySolution", + "type": "Microsoft.Common.OptionsGroup", + "label": "Deploy Azure Sentinel", + "defaultValue": "No", + "toolTip": "If 'Yes' is selected when also adding a subscription for management, ARM will deploy resources and enable them for continous compliance", + "constraints": { + "allowedValues": [ + { + "label": "Yes", + "value": "Yes" + }, + { + "label": "No", + "value": "No" + } + ] + }, + "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" } - }, - { - "name": "esVpnGw", - "type": "Microsoft.Common.OptionsGroup", - "label": "Deploy VPN Gateway", - "defaultValue": "Yes", - "visible": "[equals(steps('esConnectivityGoalState').esHub, 'Yes')]", - "toolTip": "If 'Yes' is selected when also adding a subscription for connectivity, ARM will deploy VPN gateway", - "constraints": { - "allowedValues": [ - { - "label": "Yes", - "value": "Yes" - }, - { - "label": "No", - "value": "No" - } - ] - } - }, - { - "name": "esVpnGwType", - "type": "Microsoft.Common.OptionsGroup", - "label": "Select VPN type", - "defaultValue": "Route Based (Recommended)", - "visible": "[equals(steps('esConnectivityGoalState').esVpnGw, 'Yes')]", - "toolTip": "If 'Yes' is selected when also adding a subscription for connectivity, ARM will deploy VPN gateway. Select whether it should be policy or route based.", - "constraints": { - "allowedValues": [ - { - "label": "Route Based (Recommended)", - "value": "RouteBased" - }, - { - "label": "Policy Based", - "value": "PolicyBased" - } - ] - } - }, - { - "name": "esGwRegionalOrAz", - "type": "Microsoft.Common.OptionsGroup", - "label": "Deploy zone redundant or regional VPN Gateway", - "defaultValue": "Zone redundant (recommended)", - "visible": "[and(equals(steps('esConnectivityGoalState').esVpnGw,'Yes'),or(or(or(or(or(or(or(or(equals(steps('esConnectivityGoalState').esNwLocation,'canadacentral'),equals(steps('esConnectivityGoalState').esNwLocation,'centralus')),equals(steps('esConnectivityGoalState').esNwLocation,'eastus'),equals(steps('esConnectivityGoalState').esNwLocation,'eastus2')),equals(steps('esConnectivityGoalState').esNwLocation,'southcentralus'),equals(steps('esConnectivityGoalState').esNwLocation,'westus2')),equals(steps('esConnectivityGoalState').esNwLocation,'francecentral'),equals(steps('esConnectivityGoalState').esNwLocation,'germanywestcentral')),equals(steps('esConnectivityGoalState').esNwLocation,'northeurope'),equals(steps('esConnectivityGoalState').esNwLocation,'westeurope')),equals(steps('esConnectivityGoalState').esNwLocation,'uksouth'),equals(steps('esConnectivityGoalState').esNwLocation,'southafricanorth')),equals(steps('esConnectivityGoalState').esNwLocation,'japaneast'),equals(steps('esConnectivityGoalState').esNwLocation,'southeastasia')),equals(steps('esConnectivityGoalState').esNwLocation,'southeastasia'),equals(steps('esConnectivityGoalState').esNwLocation,'australiaeast')))]", - "toolTip": "If 'Yes' is selected when also adding a subscription for connectivity, ARM will deploy Virtual Gateway to the selected region and availability zones.", - "constraints": { - "allowedValues": [ - { - "label": "Zone redundant (recommended)", - "value": "Zone" - }, - { - "label": "Regional", - "value": "Regional" - } - ] - } - }, - { - "name": "esGwNoAzSku", - "type": "Microsoft.Common.DropDown", - "label": "Select the VPN Gateway SKU", - "defaultValue": "", - "multiselect": false, - "selectAll": false, - "filter": false, - "multiLine": true, - "visible": "[and(equals(steps('esConnectivityGoalState').esVpnGw,'Yes'), not(or(or(or(or(or(or(or(or(equals(steps('esConnectivityGoalState').esNwLocation,'canadacentral'),equals(steps('esConnectivityGoalState').esNwLocation,'centralus')),equals(steps('esConnectivityGoalState').esNwLocation,'eastus'),equals(steps('esConnectivityGoalState').esNwLocation,'eastus2')),equals(steps('esConnectivityGoalState').esNwLocation,'southcentralus'),equals(steps('esConnectivityGoalState').esNwLocation,'westus2')),equals(steps('esConnectivityGoalState').esNwLocation,'francecentral'),equals(steps('esConnectivityGoalState').esNwLocation,'germanywestcentral')),equals(steps('esConnectivityGoalState').esNwLocation,'northeurope'),equals(steps('esConnectivityGoalState').esNwLocation,'westeurope')),equals(steps('esConnectivityGoalState').esNwLocation,'uksouth'),equals(steps('esConnectivityGoalState').esNwLocation,'southafricanorth')),equals(steps('esConnectivityGoalState').esNwLocation,'japaneast'),equals(steps('esConnectivityGoalState').esNwLocation,'southeastasia')),equals(steps('esConnectivityGoalState').esNwLocation,'southeastasia'),equals(steps('esConnectivityGoalState').esNwLocation,'australiaeast'))))]", - "toolTip": "Select the required SKU for the VPN gateway.", - "constraints": { - "allowedValues": [ - { - "label": "VpnGw2", - "description": "Supports BGP, max 30 S2S/VNet-VNet tunnels, max 128 P2S SSTP connections, max 500 IKEv2/OpenVPN connections, aggregate throughput is 1.25 Gbps", - "value": "VpnGw2" - }, - { - "label": "VpnGw3", - "description": "Supports BGP, max 30 S2S/VNet-VNet tunnels, max 128 P2S SSTP connections, max 1000 IKEv2/OpenVPN connections, aggregate throughput is 2.5 Gbps", - "value": "VpnGw3" - }, - { - "label": "VpnGw4", - "description": "Supports BGP, max 30 S2S/VNet-VNet tunnels, max 128 P2S SSTP connections, max 5000 IKEv2/OpenVPN connections, aggregate throughput is 5 Gbps", - "value": "VpnGw4" - }, - { - "label": "VpnGw5", - "description": "Supports BGP, max 30 S2S/VNet-VNet tunnels, max 128 P2S SSTP connections, max 10000 IKEv2/OpenVPN connections, aggregate throughput is 10 Gbps", - "value": "VpnGw5" - } - ] - } - }, - { - "name": "esGwAzSku", - "type": "Microsoft.Common.DropDown", - "label": "Select the VPN Gateway SKU", - "defaultValue": "", - "multiselect": false, - "selectAll": false, - "filter": false, - "multiLine": true, - "visible": "[and(equals(steps('esConnectivityGoalState').esVpnGw,'Yes'), equals(steps('esConnectivityGoalState').esGwRegionalOrAz, 'Zone') ,or(or(or(or(or(or(or(or(equals(steps('esConnectivityGoalState').esNwLocation,'canadacentral'),equals(steps('esConnectivityGoalState').esNwLocation,'centralus')),equals(steps('esConnectivityGoalState').esNwLocation,'eastus'),equals(steps('esConnectivityGoalState').esNwLocation,'eastus2')),equals(steps('esConnectivityGoalState').esNwLocation,'southcentralus'),equals(steps('esConnectivityGoalState').esNwLocation,'westus2')),equals(steps('esConnectivityGoalState').esNwLocation,'francecentral'),equals(steps('esConnectivityGoalState').esNwLocation,'germanywestcentral')),equals(steps('esConnectivityGoalState').esNwLocation,'northeurope'),equals(steps('esConnectivityGoalState').esNwLocation,'westeurope')),equals(steps('esConnectivityGoalState').esNwLocation,'uksouth'),equals(steps('esConnectivityGoalState').esNwLocation,'southafricanorth')),equals(steps('esConnectivityGoalState').esNwLocation,'japaneast'),equals(steps('esConnectivityGoalState').esNwLocation,'southeastasia')),equals(steps('esConnectivityGoalState').esNwLocation,'southeastasia'),equals(steps('esConnectivityGoalState').esNwLocation,'australiaeast')))]", - "toolTip": "Select the required SKU for the VPN gateway.", - "constraints": { - "allowedValues": [ - { - "label": "VpnGw2AZ", - "description": "Supports BGP, max 30 S2S/VNet-VNet tunnels, max 128 P2S SSTP connections, max 500 IKEv2/OpenVPN connections, aggregate throughput is 1.25 Gbps", - "value": "VpnGw2AZ" - }, - { - "label": "VpnGw3AZ", - "description": "Supports BGP, max 30 S2S/VNet-VNet tunnels, max 128 P2S SSTP connections, max 1000 IKEv2/OpenVPN connections, aggregate throughput is 2.5 Gbps", - "value": "VpnGw3AZ" - }, - { - "label": "VpnGw4AZ", - "description": "Supports BGP, max 30 S2S/VNet-VNet tunnels, max 128 P2S SSTP connections, max 5000 IKEv2/OpenVPN connections, aggregate throughput is 5 Gbps", - "value": "VpnGw4AZ" - }, - { - "label": "VpnGw5AZ", - "description": "Supports BGP, max 30 S2S/VNet-VNet tunnels, max 128 P2S SSTP connections, max 10000 IKEv2/OpenVPN connections, aggregate throughput is 10 Gbps", - "value": "VpnGw5AZ" - } - ] - } - }, - { - "name": "esGwRegionalSku", - "type": "Microsoft.Common.DropDown", - "label": "Select the VPN Gateway SKU", - "defaultValue": "", - "multiselect": false, - "selectAll": false, - "filter": false, - "multiLine": true, - "visible": "[and(equals(steps('esConnectivityGoalState').esVpnGw,'Yes'), equals(steps('esConnectivityGoalState').esGwRegionalOrAz, 'Regional') ,or(or(or(or(or(or(or(or(equals(steps('esConnectivityGoalState').esNwLocation,'canadacentral'),equals(steps('esConnectivityGoalState').esNwLocation,'centralus')),equals(steps('esConnectivityGoalState').esNwLocation,'eastus'),equals(steps('esConnectivityGoalState').esNwLocation,'eastus2')),equals(steps('esConnectivityGoalState').esNwLocation,'southcentralus'),equals(steps('esConnectivityGoalState').esNwLocation,'westus2')),equals(steps('esConnectivityGoalState').esNwLocation,'francecentral'),equals(steps('esConnectivityGoalState').esNwLocation,'germanywestcentral')),equals(steps('esConnectivityGoalState').esNwLocation,'northeurope'),equals(steps('esConnectivityGoalState').esNwLocation,'westeurope')),equals(steps('esConnectivityGoalState').esNwLocation,'uksouth'),equals(steps('esConnectivityGoalState').esNwLocation,'southafricanorth')),equals(steps('esConnectivityGoalState').esNwLocation,'japaneast'),equals(steps('esConnectivityGoalState').esNwLocation,'southeastasia')),equals(steps('esConnectivityGoalState').esNwLocation,'southeastasia'),equals(steps('esConnectivityGoalState').esNwLocation,'australiaeast')))]", - "toolTip": "Select the required SKU for the VPN gateway.", - "constraints": { - "allowedValues": [ - { - "label": "VpnGw2", - "description": "Supports BGP, max 30 S2S/VNet-VNet tunnels, max 128 P2S SSTP connections, max 500 IKEv2/OpenVPN connections, aggregate throughput is 1.25 Gbps", - "value": "VpnGw2" - }, - { - "label": "VpnGw3", - "description": "Supports BGP, max 30 S2S/VNet-VNet tunnels, max 128 P2S SSTP connections, max 1000 IKEv2/OpenVPN connections, aggregate throughput is 2.5 Gbps", - "value": "VpnGw3" - }, - { - "label": "VpnGw4", - "description": "Supports BGP, max 30 S2S/VNet-VNet tunnels, max 128 P2S SSTP connections, max 5000 IKEv2/OpenVPN connections, aggregate throughput is 5 Gbps", - "value": "VpnGw4" - }, - { - "label": "VpnGw5", - "description": "Supports BGP, max 30 S2S/VNet-VNet tunnels, max 128 P2S SSTP connections, max 10000 IKEv2/OpenVPN connections, aggregate throughput is 10 Gbps", - "value": "VpnGw5" - } - ] - } - }, - { - "name": "esAddressVpnOrEr", - "type": "Microsoft.Common.TextBox", - "label": "Subnet for VPN/Express route", - "toolTip": "Provide address prefix in CIDR notation (e.g 10.100.1.0/24)", - "defaultValue": "10.100.1.0/24", - "visible": "[or(equals(steps('esConnectivityGoalState').esErGw, 'Yes'), equals(steps('esConnectivityGoalState').esVpnGw, 'Yes'))]", - "constraints": { - "required": true, - "validationMessage": "The subnet network's address space, specified as one address prefixes in CIDR notation (e.g. 192.168.1.0/24)" - } - }, - { - "name": "esErGw", - "type": "Microsoft.Common.OptionsGroup", - "label": "Deploy ExpressRoute Gateway", - "defaultValue": "No", - "visible": "[equals(steps('esConnectivityGoalState').esHub, 'Yes')]", - "toolTip": "If 'Yes' is selected when also adding a subscription for connectivity, ARM will deploy Express Route gateway", - "constraints": { - "allowedValues": [ - { - "label": "Yes", - "value": "Yes" - }, - { - "label": "No", - "value": "No" - } - ] - } - }, - { - "name": "esErRegionalOrAz", - "type": "Microsoft.Common.OptionsGroup", - "label": "Deploy zone redundant or regional ExpressRoute Gateway", - "defaultValue": "Zone redundant (recommended)", - "visible": "[and(equals(steps('esConnectivityGoalState').esErGw,'Yes'),or(or(or(or(or(or(or(or(equals(steps('esConnectivityGoalState').esNwLocation,'canadacentral'),equals(steps('esConnectivityGoalState').esNwLocation,'centralus')),equals(steps('esConnectivityGoalState').esNwLocation,'eastus'),equals(steps('esConnectivityGoalState').esNwLocation,'eastus2')),equals(steps('esConnectivityGoalState').esNwLocation,'southcentralus'),equals(steps('esConnectivityGoalState').esNwLocation,'westus2')),equals(steps('esConnectivityGoalState').esNwLocation,'francecentral'),equals(steps('esConnectivityGoalState').esNwLocation,'germanywestcentral')),equals(steps('esConnectivityGoalState').esNwLocation,'northeurope'),equals(steps('esConnectivityGoalState').esNwLocation,'westeurope')),equals(steps('esConnectivityGoalState').esNwLocation,'uksouth'),equals(steps('esConnectivityGoalState').esNwLocation,'southafricanorth')),equals(steps('esConnectivityGoalState').esNwLocation,'japaneast'),equals(steps('esConnectivityGoalState').esNwLocation,'southeastasia')),equals(steps('esConnectivityGoalState').esNwLocation,'southeastasia'),equals(steps('esConnectivityGoalState').esNwLocation,'australiaeast')))]", - "toolTip": "If 'Yes' is selected when also adding a subscription for connectivity, ARM will deploy Express Route Gateway to the selected region and availability zones.", - "constraints": { - "allowedValues": [ - { - "label": "Zone redundant (recommended)", - "value": "Zone" - }, - { - "label": "Regional", - "value": "Regional" - } - ] - } - }, - { - "name": "esErAzSku", - "type": "Microsoft.Common.DropDown", - "label": "Select the ExpressRoute Gateway SKU", - "defaultValue": "", - "multiselect": false, - "selectAll": false, - "filter": false, - "multiLine": true, - "visible": "[and(equals(steps('esConnectivityGoalState').esErGw,'Yes'), equals(steps('esConnectivityGoalState').esErRegionalOrAz, 'Zone'), or(or(or(or(or(or(or(or(equals(steps('esConnectivityGoalState').esNwLocation,'canadacentral'),equals(steps('esConnectivityGoalState').esNwLocation,'centralus')),equals(steps('esConnectivityGoalState').esNwLocation,'eastus'),equals(steps('esConnectivityGoalState').esNwLocation,'eastus2')),equals(steps('esConnectivityGoalState').esNwLocation,'southcentralus'),equals(steps('esConnectivityGoalState').esNwLocation,'westus2')),equals(steps('esConnectivityGoalState').esNwLocation,'francecentral'),equals(steps('esConnectivityGoalState').esNwLocation,'germanywestcentral')),equals(steps('esConnectivityGoalState').esNwLocation,'northeurope'),equals(steps('esConnectivityGoalState').esNwLocation,'westeurope')),equals(steps('esConnectivityGoalState').esNwLocation,'uksouth'),equals(steps('esConnectivityGoalState').esNwLocation,'southafricanorth')),equals(steps('esConnectivityGoalState').esNwLocation,'japaneast'),equals(steps('esConnectivityGoalState').esNwLocation,'southeastasia')),equals(steps('esConnectivityGoalState').esNwLocation,'southeastasia'),equals(steps('esConnectivityGoalState').esNwLocation,'australiaeast')))]", - "toolTip": "Select the required SKU for the Express Route gateway.", - "constraints": { - "allowedValues": [ - { - "label": "ErGw1AZ", - "description": "Megabits per second 1000, packets per second 100,000, connections per second 7000, max number of cicuit connections is 4", - "value": "ErGw1AZ" - }, - { - "label": "ErGw2AZ", - "description": "Megabits per second 2000, packets per second 250,000, connections per second 14000, max number of cicuit connections is 8", - "value": "ErGw2AZ" - }, - { - "label": "ErGw3AZ", - "description": "Megabits per second 10,000, packets per second 1,000,000, connections per second 28,000, max number of cicuit connections is 16", - "value": "ErGw3AZ" - } - ] - } - }, - { - "name": "esErRegionalSku", - "type": "Microsoft.Common.DropDown", - "label": "Select the ExpressRoute Gateway SKU", - "defaultValue": "", - "multiselect": false, - "selectAll": false, - "filter": false, - "multiLine": true, - "visible": "[and(equals(steps('esConnectivityGoalState').esErGw,'Yes'), equals(steps('esConnectivityGoalState').esErRegionalOrAz, 'Regional'), or(or(or(or(or(or(or(or(equals(steps('esConnectivityGoalState').esNwLocation,'canadacentral'),equals(steps('esConnectivityGoalState').esNwLocation,'centralus')),equals(steps('esConnectivityGoalState').esNwLocation,'eastus'),equals(steps('esConnectivityGoalState').esNwLocation,'eastus2')),equals(steps('esConnectivityGoalState').esNwLocation,'southcentralus'),equals(steps('esConnectivityGoalState').esNwLocation,'westus2')),equals(steps('esConnectivityGoalState').esNwLocation,'francecentral'),equals(steps('esConnectivityGoalState').esNwLocation,'germanywestcentral')),equals(steps('esConnectivityGoalState').esNwLocation,'northeurope'),equals(steps('esConnectivityGoalState').esNwLocation,'westeurope')),equals(steps('esConnectivityGoalState').esNwLocation,'uksouth'),equals(steps('esConnectivityGoalState').esNwLocation,'southafricanorth')),equals(steps('esConnectivityGoalState').esNwLocation,'japaneast'),equals(steps('esConnectivityGoalState').esNwLocation,'southeastasia')),equals(steps('esConnectivityGoalState').esNwLocation,'southeastasia'),equals(steps('esConnectivityGoalState').esNwLocation,'australiaeast')))]", - "toolTip": "Select the required SKU for the Express Route gateway.", - "constraints": { - "allowedValues": [ - { - "label": "Standard", - "description": "Megabits per second 1000, packets per second 100,000, connections per second 7000, max number of cicuit connections is 4", - "value": "Standard" - }, - { - "label": "HighPerformance", - "description": "Megabits per second 2000, packets per second 250,000, connections per second 14000, max number of cicuit connections is 8", - "value": "HighPerformance" - }, - { - "label": "UltraPerformance", - "description": "Megabits per second 10,000, packets per second 1,000,000, connections per second 28,000, max number of cicuit connections is 16", - "value": "UltraPerformance" - } - ] - } - }, - { - "name": "esErNoAzSku", - "type": "Microsoft.Common.DropDown", - "label": "Select the ExpressRoute Gateway SKU", - "defaultValue": "", - "multiselect": false, - "selectAll": false, - "filter": false, - "multiLine": true, - "visible": "[and(equals(steps('esConnectivityGoalState').esErGw,'Yes'), not(or(or(or(or(or(or(or(or(equals(steps('esConnectivityGoalState').esNwLocation,'canadacentral'),equals(steps('esConnectivityGoalState').esNwLocation,'centralus')),equals(steps('esConnectivityGoalState').esNwLocation,'eastus'),equals(steps('esConnectivityGoalState').esNwLocation,'eastus2')),equals(steps('esConnectivityGoalState').esNwLocation,'southcentralus'),equals(steps('esConnectivityGoalState').esNwLocation,'westus2')),equals(steps('esConnectivityGoalState').esNwLocation,'francecentral'),equals(steps('esConnectivityGoalState').esNwLocation,'germanywestcentral')),equals(steps('esConnectivityGoalState').esNwLocation,'northeurope'),equals(steps('esConnectivityGoalState').esNwLocation,'westeurope')),equals(steps('esConnectivityGoalState').esNwLocation,'uksouth'),equals(steps('esConnectivityGoalState').esNwLocation,'southafricanorth')),equals(steps('esConnectivityGoalState').esNwLocation,'japaneast'),equals(steps('esConnectivityGoalState').esNwLocation,'southeastasia')),equals(steps('esConnectivityGoalState').esNwLocation,'southeastasia'),equals(steps('esConnectivityGoalState').esNwLocation,'australiaeast'))))]", - "toolTip": "Select the required SKU for the Express Route gateway.", - "constraints": { - "allowedValues": [ - { - "label": "Standard", - "description": "Megabits per second 1000, packets per second 100,000, connections per second 7000, max number of cicuit connections is 4", - "value": "Standard" - }, - { - "label": "HighPerformance", - "description": "Megabits per second 2000, packets per second 250,000, connections per second 14000, max number of cicuit connections is 8", - "value": "HighPerformance" - }, - { - "label": "UltraPerformance", - "description": "Megabits per second 10,000, packets per second 1,000,000, connections per second 28,000, max number of cicuit connections is 16", - "value": "UltraPerformance" - } - ] - } - }, - { - "name": "esAzFw", - "type": "Microsoft.Common.OptionsGroup", - "label": "Deploy Azure Firewall", - "defaultValue": "No", - "visible": "[equals(steps('esConnectivityGoalState').esHub, 'Yes')]", - "toolTip": "If 'Yes' is selected when also adding a subscription for connectivity, ARM will deploy Azure Firewall", - "constraints": { - "allowedValues": [ - { - "label": "Yes (recommended)", - "value": "Yes" - }, - { - "label": "No", - "value": "No" - } - ] - } - }, - { - "name": "esAzFwDns", - "type": "Microsoft.Common.OptionsGroup", - "label": "Enable Azure Firewall as a DNS proxy", - "defaultValue": "No", - "visible": "[equals(steps('esConnectivityGoalState').esAzFw,'Yes')]", - "toolTip": "If 'Yes' is selected when also adding a subscription for connectivity, ARM will enable Azure Firewall as a DNS Proxy.", - "constraints": { - "allowedValues": [ - { - "label": "Yes", - "value": "Yes" - }, - { - "label": "No", - "value": "No" - } - ] - } - }, - { - "name": "esFwAz", - "type": "Microsoft.Common.DropDown", - "label": "Select Availability Zones for the Azure Firewall", - "defaultValue": "None", - "multiselect": true, - "selectAll": true, - "filter": true, - "visible": "[and(equals(steps('esConnectivityGoalState').esAzFw,'Yes'),or(or(or(or(or(or(or(or(equals(steps('esConnectivityGoalState').esNwLocation,'canadacentral'),equals(steps('esConnectivityGoalState').esNwLocation,'centralus')),equals(steps('esConnectivityGoalState').esNwLocation,'eastus'),equals(steps('esConnectivityGoalState').esNwLocation,'eastus2')),equals(steps('esConnectivityGoalState').esNwLocation,'southcentralus'),equals(steps('esConnectivityGoalState').esNwLocation,'westus2')),equals(steps('esConnectivityGoalState').esNwLocation,'francecentral'),equals(steps('esConnectivityGoalState').esNwLocation,'germanywestcentral')),equals(steps('esConnectivityGoalState').esNwLocation,'northeurope'),equals(steps('esConnectivityGoalState').esNwLocation,'westeurope')),equals(steps('esConnectivityGoalState').esNwLocation,'uksouth'),equals(steps('esConnectivityGoalState').esNwLocation,'southafricanorth')),equals(steps('esConnectivityGoalState').esNwLocation,'japaneast'),equals(steps('esConnectivityGoalState').esNwLocation,'southeastasia')),equals(steps('esConnectivityGoalState').esNwLocation,'southeastasia'),equals(steps('esConnectivityGoalState').esNwLocation,'australiaeast')))]", - "toolTip": "If 'Yes' is selected when also adding a subscription for connectivity, ARM will deploy Azure Firewall to the selected region and availability zones.", - "constraints": { - "required": true, - "allowedValues": [ - { - "label": "Zone 1", - "value": "1" - }, - { - "label": "Zone 2", - "value": "2" - }, - { - "label": "Zone 3", - "value": "3" - } - ] - } - }, - { - "name": "esAddressFw", - "type": "Microsoft.Common.TextBox", - "label": "Subnet for Azure Firewall", - "toolTip": "Provide address prefix in CIDR notation (e.g 10.100.0.0/24)", - "defaultValue": "10.100.0.0/24", - "visible": "[equals(steps('esConnectivityGoalState').esAzFw, 'Yes')]", - "constraints": { - "required": true, - "validationMessage": "The subnet network's address space, specified as one address prefixes in CIDR notation (e.g. 192.168.1.0/24)" - } - } - ] - }, - { - "name": "lzGoalState", - "label": "Landing zone configuration", - "subLabel": { - "preValidation": "", - "postValidation": "" + ] }, - "bladeTitle": "lzGs", - "elements": [ - { - "name": "infoBox1", - "type": "Microsoft.Common.InfoBox", - "visible": true, - "options": { - "icon": "Info", - "text": "You can optionally provide subscriptions for your first 'Online' and 'Corp' landing zones and assign recommended policies that will ensure workloads will be secure, monitored, and protected according to best practices.", - "uri": "https://github.com/Azure/Enterprise-Scale/blob/main/docs/Deploy/ES-schema.md" - } + { + "name": "esConnectivityGoalState", + "label": "Connectivity (Hub & Spoke)", + "subLabel": { + "preValidation": "Select 'Yes' if goal state should be enforced during deployment. Select 'No' if you want to do it post deployment using Azure Policy.", + "postValidation": "Done" }, - { - "name": "onlineText", - "type": "Microsoft.Common.TextBlock", - "visible": true, - "options": { - "text": "Select the subscriptions you want to use to host your Online landing zones.", - "link": { - "label": "Learn more", - "uri": "https://docs.microsoft.com/azure/azure-monitor/insights/solutions" + "bladeTitle": "lzGs", + "elements": [ + { + "name": "infoBox1", + "type": "Microsoft.Common.InfoBox", + "visible": true, + "options": { + "icon": "Info", + "text": "Enterprise Scale allows you to enable hybrid connectivity with on premises using Hub & Spoke topology. Please note, all connectivity components required will be deployed to the Platform Subscription.", + "uri": "https://github.com/Azure/Enterprise-Scale/blob/main/docs/reference/Readme.md" } - } - }, - { - "name": "lzOnlineSubsApi", - "type": "Microsoft.Solutions.ArmApiControl", - "request": { - "method": "GET", - "path": "subscriptions?api-version=2020-01-01" - } - }, - { - "name": "esOnlineLzSub", - "type": "Microsoft.Common.DropDown", - "label": "Online landing zone subscriptions (optional)", - "toolTip": "", - "multiselect": true, - "selectAll": true, - "filter": true, - "filterPlaceholder": "Filter items ...", - "multiLine": true, - "visible": true, - "constraints": { - "allowedValues": "[map(steps('lzGoalState').lzOnlineSubsApi.value, (sub) => parse(concat('{\"label\":\"', sub.displayName, '\",\"description\":\"', sub.subscriptionId, '\",\"value\":\"', toLower(sub.subscriptionId), '\"}')) )]", - "required": false - } - }, - { - "name": "corpText", - "type": "Microsoft.Common.TextBlock", - "visible": true, - "options": { - "text": "Select the subscriptions you want to use to host your Corp landing zones.", - "link": { - "label": "Learn more", - "uri": "https://docs.microsoft.com/azure/azure-monitor/insights/solutions" + }, + { + "name": "esHub", + "type": "Microsoft.Common.OptionsGroup", + "label": "Deploy virtual hub", + "defaultValue": "Yes", + "toolTip": "If 'Yes' is selected, ARM will deploy a virtual network for hub", + "constraints": { + "allowedValues": [ + { + "label": "Yes", + "value": "Yes" + }, + { + "label": "No", + "value": "No" + } + ] + }, + "visible": true + }, + { + "name": "nwSubsApi", + "type": "Microsoft.Solutions.ArmApiControl", + "request": { + "method": "GET", + "path": "subscriptions?api-version=2020-01-01" } - } - }, - { - "name": "lzCorpSubsApi", - "type": "Microsoft.Solutions.ArmApiControl", - "request": { - "method": "GET", - "path": "subscriptions?api-version=2020-01-01" - } - }, - { - "name": "esCorpLzSub", - "type": "Microsoft.Common.DropDown", - "label": "Corp landing zone subscriptions (optional)", - "toolTip": "", - "multiselect": true, - "selectAll": true, - "filter": true, - "filterPlaceholder": "Filter items ...", - "multiLine": true, - "visible": true, - "constraints": { - "allowedValues": "[map(steps('lzGoalState').lzCorpSubsApi.value, (sub) => parse(concat('{\"label\":\"', sub.displayName, '\",\"description\":\"', sub.subscriptionId, '\",\"value\":\"', toLower(sub.subscriptionId), '\"}')) )]", - "required": false - } - }, - { - "name": "azMonText", - "type": "Microsoft.Common.TextBlock", - "visible": true, - "options": { - "text": "Select which of the the recommended policies you will assign to all your landing zones. That includes Online, Corp and additional Landing Zone's types you may add in the future.", - "link": { - "label": "Learn more", - "uri": "https://docs.microsoft.com/en-us/azure/cloud-adoption-framework/ready/enterprise-scale/design-principles#policy-driven-governance" + }, + { + "name": "esConnectivitySub", + "type": "Microsoft.Common.DropDown", + "label": "Platform subscription (required)", + "toolTip": "You did not provided a Platform Subscription yet. You must allocate one now. Please note, this Subscription will be moved to the platform Management Group, and ARM will deploy the first networking hub and requisite settings. We recommend using a new Subscription with no existing resources.", + "multiselect": false, + "selectAll": true, + "filter": true, + "filterPlaceholder": "Filter items ...", + "multiLine": true, + "defaultValue": "[if(not(empty(steps('esGoalState').esMgmtSub)),steps('esGoalState').esMgmtSub,'')]", + "visible": "[and(equals(steps('esConnectivityGoalState').esHub,'Yes'),empty(steps('esGoalState').esMgmtSub))]", + "constraints": { + "allowedValues": "[map(steps('esConnectivityGoalState').nwSubsApi.value, (sub) => parse(concat('{\"label\":\"', sub.displayName, '\",\"description\":\"', sub.subscriptionId, '\",\"value\":\"', toLower(sub.subscriptionId), '\"}')) )]", + "required": "[and(equals(steps('esConnectivityGoalState').esHub,'Yes'),empty(steps('esGoalState').esMgmtSub))]" } - } - }, - { - "name": "esLzDdoS", - "type": "Microsoft.Common.OptionsGroup", - "label": "Enable DDoS Protection Standard", - "defaultValue": "No", - "visible": "[and(equals(steps('esConnectivityGoalState').esHub,'Yes'),equals(steps('esConnectivityGoalState').esDdoS,'Yes'))]", - "toolTip": "If 'Yes' is selected when also adding a connectivity subscription earlier, DDoS Protection Standard will be enabled.", - "constraints": { - "allowedValues": [ - { - "label": "Yes (recommended)", - "value": "Yes" - }, - { - "label": "No", - "value": "No" - } - ] - } - }, - { - "name": "esLzPrivateLink", - "type": "Microsoft.Common.OptionsGroup", - "label": "Prevent usage of Public Endpoints for PaaS services in the corp connected landing zones", - "defaultValue": "Yes (recommended)", - "visible": true, - "toolTip": "If 'Yes' is selected then Azure Policy will prevent PaaS resources to use public endpoints.", - "constraints": { - "allowedValues": [ - { - "label": "Yes (recommended)", - "value": "Yes" - }, - { - "label": "No", - "value": "No" + }, + { + "name": "esAddressHub", + "type": "Microsoft.Common.TextBox", + "label": "Address space (required for virtual network hub)", + "toolTip": "Provide address prefix in CIDR notation (e.g 10.100.0.0/16)", + "defaultValue": "10.100.0.0/16", + "visible": "[equals(steps('esConnectivityGoalState').esHub, 'Yes')]", + "constraints": { + "required": true, + "validationMessage": "The virtual hubs network's address space, specified as one address prefixes in CIDR notation (e.g. 192.168.1.0/24)" + } + }, + { + "name": "esLocationsApi", + "type": "Microsoft.Solutions.ArmApiControl", + "request": { + "method": "GET", + "path": "locations?api-version=2019-11-01" + } + }, + { + "name": "esNwLocation", + "type": "Microsoft.Common.DropDown", + "label": "Region for the first virtual network hub", + "filter": true, + "toolTip": "Select the target region for you connectivity deployment (requires you to provide a subscriptionId for connectivity)", + "constraints": { + "allowedValues": "[map(steps('esConnectivityGoalState').esLocationsApi.value, (item) => parse(concat('{\"label\":\"', item.displayName, '\",\"value\":\"', item.name, '\"}')))]", + "required": true + }, + "visible": "[equals(steps('esConnectivityGoalState').esHub, 'Yes')]" + }, + { + "name": "esDdoS", + "type": "Microsoft.Common.OptionsGroup", + "label": "Enable DDoS Protection Standard", + "defaultValue": "No", + "visible": "[equals(steps('esConnectivityGoalState').esHub,'Yes')]", + "toolTip": "If 'Yes' is selected when also adding a connectivity subscription, DDoS Protection Standard will be enabled.", + "constraints": { + "allowedValues": [ + { + "label": "Yes (recommended)", + "value": "Yes" + }, + { + "label": "No", + "value": "No" + } + ] + } + }, + { + "name": "textBlock0", + "type": "Microsoft.Common.TextBlock", + "visible": "[equals(steps('esConnectivityGoalState').esHub, 'Yes')]", + "options": { + "text": "To know more about Azure DDos protection pricing.", + "link": { + "label": "Azure DDoS Pricing", + "uri": "https://azure.microsoft.com/en-us/pricing/details/ddos-protection/" } - ] + } + }, + { + "name": "esVpnGw", + "type": "Microsoft.Common.OptionsGroup", + "label": "Deploy VPN Gateway", + "defaultValue": "Yes", + "visible": "[equals(steps('esConnectivityGoalState').esHub, 'Yes')]", + "toolTip": "If 'Yes' is selected when also adding a subscription for connectivity, ARM will deploy VPN gateway", + "constraints": { + "allowedValues": [ + { + "label": "Yes", + "value": "Yes" + }, + { + "label": "No", + "value": "No" + } + ] + } + }, + { + "name": "esVpnGwType", + "type": "Microsoft.Common.OptionsGroup", + "label": "Select VPN type", + "defaultValue": "Route Based (Recommended)", + "visible": "[equals(steps('esConnectivityGoalState').esVpnGw, 'Yes')]", + "toolTip": "If 'Yes' is selected when also adding a subscription for connectivity, ARM will deploy VPN gateway. Select whether it should be policy or route based.", + "constraints": { + "allowedValues": [ + { + "label": "Route Based (Recommended)", + "value": "RouteBased" + }, + { + "label": "Policy Based", + "value": "PolicyBased" + } + ] + } + }, + { + "name": "esGwRegionalOrAz", + "type": "Microsoft.Common.OptionsGroup", + "label": "Deploy zone redundant or regional VPN Gateway", + "defaultValue": "Zone redundant (recommended)", + "visible": "[and(equals(steps('esConnectivityGoalState').esVpnGw,'Yes'),or(or(or(or(or(or(or(or(equals(steps('esConnectivityGoalState').esNwLocation,'canadacentral'),equals(steps('esConnectivityGoalState').esNwLocation,'centralus')),equals(steps('esConnectivityGoalState').esNwLocation,'eastus'),equals(steps('esConnectivityGoalState').esNwLocation,'eastus2')),equals(steps('esConnectivityGoalState').esNwLocation,'southcentralus'),equals(steps('esConnectivityGoalState').esNwLocation,'westus2')),equals(steps('esConnectivityGoalState').esNwLocation,'francecentral'),equals(steps('esConnectivityGoalState').esNwLocation,'germanywestcentral')),equals(steps('esConnectivityGoalState').esNwLocation,'northeurope'),equals(steps('esConnectivityGoalState').esNwLocation,'westeurope')),equals(steps('esConnectivityGoalState').esNwLocation,'uksouth'),equals(steps('esConnectivityGoalState').esNwLocation,'southafricanorth')),equals(steps('esConnectivityGoalState').esNwLocation,'japaneast'),equals(steps('esConnectivityGoalState').esNwLocation,'southeastasia')),equals(steps('esConnectivityGoalState').esNwLocation,'southeastasia'),equals(steps('esConnectivityGoalState').esNwLocation,'australiaeast')))]", + "toolTip": "If 'Yes' is selected when also adding a subscription for connectivity, ARM will deploy Virtual Gateway to the selected region and availability zones.", + "constraints": { + "allowedValues": [ + { + "label": "Zone redundant (recommended)", + "value": "Zone" + }, + { + "label": "Regional", + "value": "Regional" + } + ] + } + }, + { + "name": "esGwNoAzSku", + "type": "Microsoft.Common.DropDown", + "label": "Select the VPN Gateway SKU", + "defaultValue": "", + "multiselect": false, + "selectAll": false, + "filter": false, + "multiLine": true, + "visible": "[and(equals(steps('esConnectivityGoalState').esVpnGw,'Yes'), not(or(or(or(or(or(or(or(or(equals(steps('esConnectivityGoalState').esNwLocation,'canadacentral'),equals(steps('esConnectivityGoalState').esNwLocation,'centralus')),equals(steps('esConnectivityGoalState').esNwLocation,'eastus'),equals(steps('esConnectivityGoalState').esNwLocation,'eastus2')),equals(steps('esConnectivityGoalState').esNwLocation,'southcentralus'),equals(steps('esConnectivityGoalState').esNwLocation,'westus2')),equals(steps('esConnectivityGoalState').esNwLocation,'francecentral'),equals(steps('esConnectivityGoalState').esNwLocation,'germanywestcentral')),equals(steps('esConnectivityGoalState').esNwLocation,'northeurope'),equals(steps('esConnectivityGoalState').esNwLocation,'westeurope')),equals(steps('esConnectivityGoalState').esNwLocation,'uksouth'),equals(steps('esConnectivityGoalState').esNwLocation,'southafricanorth')),equals(steps('esConnectivityGoalState').esNwLocation,'japaneast'),equals(steps('esConnectivityGoalState').esNwLocation,'southeastasia')),equals(steps('esConnectivityGoalState').esNwLocation,'southeastasia'),equals(steps('esConnectivityGoalState').esNwLocation,'australiaeast'))))]", + "toolTip": "Select the required SKU for the VPN gateway.", + "constraints": { + "allowedValues": [ + { + "label": "VpnGw2", + "description": "Supports BGP, max 30 S2S/VNet-VNet tunnels, max 128 P2S SSTP connections, max 500 IKEv2/OpenVPN connections, aggregate throughput is 1.25 Gbps", + "value": "VpnGw2" + }, + { + "label": "VpnGw3", + "description": "Supports BGP, max 30 S2S/VNet-VNet tunnels, max 128 P2S SSTP connections, max 1000 IKEv2/OpenVPN connections, aggregate throughput is 2.5 Gbps", + "value": "VpnGw3" + }, + { + "label": "VpnGw4", + "description": "Supports BGP, max 30 S2S/VNet-VNet tunnels, max 128 P2S SSTP connections, max 5000 IKEv2/OpenVPN connections, aggregate throughput is 5 Gbps", + "value": "VpnGw4" + }, + { + "label": "VpnGw5", + "description": "Supports BGP, max 30 S2S/VNet-VNet tunnels, max 128 P2S SSTP connections, max 10000 IKEv2/OpenVPN connections, aggregate throughput is 10 Gbps", + "value": "VpnGw5" + } + ] + } + }, + { + "name": "esGwAzSku", + "type": "Microsoft.Common.DropDown", + "label": "Select the VPN Gateway SKU", + "defaultValue": "", + "multiselect": false, + "selectAll": false, + "filter": false, + "multiLine": true, + "visible": "[and(equals(steps('esConnectivityGoalState').esVpnGw,'Yes'), equals(steps('esConnectivityGoalState').esGwRegionalOrAz, 'Zone') ,or(or(or(or(or(or(or(or(equals(steps('esConnectivityGoalState').esNwLocation,'canadacentral'),equals(steps('esConnectivityGoalState').esNwLocation,'centralus')),equals(steps('esConnectivityGoalState').esNwLocation,'eastus'),equals(steps('esConnectivityGoalState').esNwLocation,'eastus2')),equals(steps('esConnectivityGoalState').esNwLocation,'southcentralus'),equals(steps('esConnectivityGoalState').esNwLocation,'westus2')),equals(steps('esConnectivityGoalState').esNwLocation,'francecentral'),equals(steps('esConnectivityGoalState').esNwLocation,'germanywestcentral')),equals(steps('esConnectivityGoalState').esNwLocation,'northeurope'),equals(steps('esConnectivityGoalState').esNwLocation,'westeurope')),equals(steps('esConnectivityGoalState').esNwLocation,'uksouth'),equals(steps('esConnectivityGoalState').esNwLocation,'southafricanorth')),equals(steps('esConnectivityGoalState').esNwLocation,'japaneast'),equals(steps('esConnectivityGoalState').esNwLocation,'southeastasia')),equals(steps('esConnectivityGoalState').esNwLocation,'southeastasia'),equals(steps('esConnectivityGoalState').esNwLocation,'australiaeast')))]", + "toolTip": "Select the required SKU for the VPN gateway.", + "constraints": { + "allowedValues": [ + { + "label": "VpnGw2AZ", + "description": "Supports BGP, max 30 S2S/VNet-VNet tunnels, max 128 P2S SSTP connections, max 500 IKEv2/OpenVPN connections, aggregate throughput is 1.25 Gbps", + "value": "VpnGw2AZ" + }, + { + "label": "VpnGw3AZ", + "description": "Supports BGP, max 30 S2S/VNet-VNet tunnels, max 128 P2S SSTP connections, max 1000 IKEv2/OpenVPN connections, aggregate throughput is 2.5 Gbps", + "value": "VpnGw3AZ" + }, + { + "label": "VpnGw4AZ", + "description": "Supports BGP, max 30 S2S/VNet-VNet tunnels, max 128 P2S SSTP connections, max 5000 IKEv2/OpenVPN connections, aggregate throughput is 5 Gbps", + "value": "VpnGw4AZ" + }, + { + "label": "VpnGw5AZ", + "description": "Supports BGP, max 30 S2S/VNet-VNet tunnels, max 128 P2S SSTP connections, max 10000 IKEv2/OpenVPN connections, aggregate throughput is 10 Gbps", + "value": "VpnGw5AZ" + } + ] + } + }, + { + "name": "esGwRegionalSku", + "type": "Microsoft.Common.DropDown", + "label": "Select the VPN Gateway SKU", + "defaultValue": "", + "multiselect": false, + "selectAll": false, + "filter": false, + "multiLine": true, + "visible": "[and(equals(steps('esConnectivityGoalState').esVpnGw,'Yes'), equals(steps('esConnectivityGoalState').esGwRegionalOrAz, 'Regional') ,or(or(or(or(or(or(or(or(equals(steps('esConnectivityGoalState').esNwLocation,'canadacentral'),equals(steps('esConnectivityGoalState').esNwLocation,'centralus')),equals(steps('esConnectivityGoalState').esNwLocation,'eastus'),equals(steps('esConnectivityGoalState').esNwLocation,'eastus2')),equals(steps('esConnectivityGoalState').esNwLocation,'southcentralus'),equals(steps('esConnectivityGoalState').esNwLocation,'westus2')),equals(steps('esConnectivityGoalState').esNwLocation,'francecentral'),equals(steps('esConnectivityGoalState').esNwLocation,'germanywestcentral')),equals(steps('esConnectivityGoalState').esNwLocation,'northeurope'),equals(steps('esConnectivityGoalState').esNwLocation,'westeurope')),equals(steps('esConnectivityGoalState').esNwLocation,'uksouth'),equals(steps('esConnectivityGoalState').esNwLocation,'southafricanorth')),equals(steps('esConnectivityGoalState').esNwLocation,'japaneast'),equals(steps('esConnectivityGoalState').esNwLocation,'southeastasia')),equals(steps('esConnectivityGoalState').esNwLocation,'southeastasia'),equals(steps('esConnectivityGoalState').esNwLocation,'australiaeast')))]", + "toolTip": "Select the required SKU for the VPN gateway.", + "constraints": { + "allowedValues": [ + { + "label": "VpnGw2", + "description": "Supports BGP, max 30 S2S/VNet-VNet tunnels, max 128 P2S SSTP connections, max 500 IKEv2/OpenVPN connections, aggregate throughput is 1.25 Gbps", + "value": "VpnGw2" + }, + { + "label": "VpnGw3", + "description": "Supports BGP, max 30 S2S/VNet-VNet tunnels, max 128 P2S SSTP connections, max 1000 IKEv2/OpenVPN connections, aggregate throughput is 2.5 Gbps", + "value": "VpnGw3" + }, + { + "label": "VpnGw4", + "description": "Supports BGP, max 30 S2S/VNet-VNet tunnels, max 128 P2S SSTP connections, max 5000 IKEv2/OpenVPN connections, aggregate throughput is 5 Gbps", + "value": "VpnGw4" + }, + { + "label": "VpnGw5", + "description": "Supports BGP, max 30 S2S/VNet-VNet tunnels, max 128 P2S SSTP connections, max 10000 IKEv2/OpenVPN connections, aggregate throughput is 10 Gbps", + "value": "VpnGw5" + } + ] + } + }, + { + "name": "esAddressVpnOrEr", + "type": "Microsoft.Common.TextBox", + "label": "Subnet for VPN/Express route", + "toolTip": "Provide address prefix in CIDR notation (e.g 10.100.1.0/24)", + "defaultValue": "10.100.1.0/24", + "visible": "[or(equals(steps('esConnectivityGoalState').esErGw, 'Yes'), equals(steps('esConnectivityGoalState').esVpnGw, 'Yes'))]", + "constraints": { + "required": true, + "validationMessage": "The subnet network's address space, specified as one address prefixes in CIDR notation (e.g. 192.168.1.0/24)" + } + }, + { + "name": "esErGw", + "type": "Microsoft.Common.OptionsGroup", + "label": "Deploy ExpressRoute Gateway", + "defaultValue": "No", + "visible": "[equals(steps('esConnectivityGoalState').esHub, 'Yes')]", + "toolTip": "If 'Yes' is selected when also adding a subscription for connectivity, ARM will deploy Express Route gateway", + "constraints": { + "allowedValues": [ + { + "label": "Yes", + "value": "Yes" + }, + { + "label": "No", + "value": "No" + } + ] + } + }, + { + "name": "esErRegionalOrAz", + "type": "Microsoft.Common.OptionsGroup", + "label": "Deploy zone redundant or regional ExpressRoute Gateway", + "defaultValue": "Zone redundant (recommended)", + "visible": "[and(equals(steps('esConnectivityGoalState').esErGw,'Yes'),or(or(or(or(or(or(or(or(equals(steps('esConnectivityGoalState').esNwLocation,'canadacentral'),equals(steps('esConnectivityGoalState').esNwLocation,'centralus')),equals(steps('esConnectivityGoalState').esNwLocation,'eastus'),equals(steps('esConnectivityGoalState').esNwLocation,'eastus2')),equals(steps('esConnectivityGoalState').esNwLocation,'southcentralus'),equals(steps('esConnectivityGoalState').esNwLocation,'westus2')),equals(steps('esConnectivityGoalState').esNwLocation,'francecentral'),equals(steps('esConnectivityGoalState').esNwLocation,'germanywestcentral')),equals(steps('esConnectivityGoalState').esNwLocation,'northeurope'),equals(steps('esConnectivityGoalState').esNwLocation,'westeurope')),equals(steps('esConnectivityGoalState').esNwLocation,'uksouth'),equals(steps('esConnectivityGoalState').esNwLocation,'southafricanorth')),equals(steps('esConnectivityGoalState').esNwLocation,'japaneast'),equals(steps('esConnectivityGoalState').esNwLocation,'southeastasia')),equals(steps('esConnectivityGoalState').esNwLocation,'southeastasia'),equals(steps('esConnectivityGoalState').esNwLocation,'australiaeast')))]", + "toolTip": "If 'Yes' is selected when also adding a subscription for connectivity, ARM will deploy Express Route Gateway to the selected region and availability zones.", + "constraints": { + "allowedValues": [ + { + "label": "Zone redundant (recommended)", + "value": "Zone" + }, + { + "label": "Regional", + "value": "Regional" + } + ] + } + }, + { + "name": "esErAzSku", + "type": "Microsoft.Common.DropDown", + "label": "Select the ExpressRoute Gateway SKU", + "defaultValue": "", + "multiselect": false, + "selectAll": false, + "filter": false, + "multiLine": true, + "visible": "[and(equals(steps('esConnectivityGoalState').esErGw,'Yes'), equals(steps('esConnectivityGoalState').esErRegionalOrAz, 'Zone'), or(or(or(or(or(or(or(or(equals(steps('esConnectivityGoalState').esNwLocation,'canadacentral'),equals(steps('esConnectivityGoalState').esNwLocation,'centralus')),equals(steps('esConnectivityGoalState').esNwLocation,'eastus'),equals(steps('esConnectivityGoalState').esNwLocation,'eastus2')),equals(steps('esConnectivityGoalState').esNwLocation,'southcentralus'),equals(steps('esConnectivityGoalState').esNwLocation,'westus2')),equals(steps('esConnectivityGoalState').esNwLocation,'francecentral'),equals(steps('esConnectivityGoalState').esNwLocation,'germanywestcentral')),equals(steps('esConnectivityGoalState').esNwLocation,'northeurope'),equals(steps('esConnectivityGoalState').esNwLocation,'westeurope')),equals(steps('esConnectivityGoalState').esNwLocation,'uksouth'),equals(steps('esConnectivityGoalState').esNwLocation,'southafricanorth')),equals(steps('esConnectivityGoalState').esNwLocation,'japaneast'),equals(steps('esConnectivityGoalState').esNwLocation,'southeastasia')),equals(steps('esConnectivityGoalState').esNwLocation,'southeastasia'),equals(steps('esConnectivityGoalState').esNwLocation,'australiaeast')))]", + "toolTip": "Select the required SKU for the Express Route gateway.", + "constraints": { + "allowedValues": [ + { + "label": "ErGw1AZ", + "description": "Megabits per second 1000, packets per second 100,000, connections per second 7000, max number of cicuit connections is 4", + "value": "ErGw1AZ" + }, + { + "label": "ErGw2AZ", + "description": "Megabits per second 2000, packets per second 250,000, connections per second 14000, max number of cicuit connections is 8", + "value": "ErGw2AZ" + }, + { + "label": "ErGw3AZ", + "description": "Megabits per second 10,000, packets per second 1,000,000, connections per second 28,000, max number of cicuit connections is 16", + "value": "ErGw3AZ" + } + ] + } + }, + { + "name": "esErRegionalSku", + "type": "Microsoft.Common.DropDown", + "label": "Select the ExpressRoute Gateway SKU", + "defaultValue": "", + "multiselect": false, + "selectAll": false, + "filter": false, + "multiLine": true, + "visible": "[and(equals(steps('esConnectivityGoalState').esErGw,'Yes'), equals(steps('esConnectivityGoalState').esErRegionalOrAz, 'Regional'), or(or(or(or(or(or(or(or(equals(steps('esConnectivityGoalState').esNwLocation,'canadacentral'),equals(steps('esConnectivityGoalState').esNwLocation,'centralus')),equals(steps('esConnectivityGoalState').esNwLocation,'eastus'),equals(steps('esConnectivityGoalState').esNwLocation,'eastus2')),equals(steps('esConnectivityGoalState').esNwLocation,'southcentralus'),equals(steps('esConnectivityGoalState').esNwLocation,'westus2')),equals(steps('esConnectivityGoalState').esNwLocation,'francecentral'),equals(steps('esConnectivityGoalState').esNwLocation,'germanywestcentral')),equals(steps('esConnectivityGoalState').esNwLocation,'northeurope'),equals(steps('esConnectivityGoalState').esNwLocation,'westeurope')),equals(steps('esConnectivityGoalState').esNwLocation,'uksouth'),equals(steps('esConnectivityGoalState').esNwLocation,'southafricanorth')),equals(steps('esConnectivityGoalState').esNwLocation,'japaneast'),equals(steps('esConnectivityGoalState').esNwLocation,'southeastasia')),equals(steps('esConnectivityGoalState').esNwLocation,'southeastasia'),equals(steps('esConnectivityGoalState').esNwLocation,'australiaeast')))]", + "toolTip": "Select the required SKU for the Express Route gateway.", + "constraints": { + "allowedValues": [ + { + "label": "Standard", + "description": "Megabits per second 1000, packets per second 100,000, connections per second 7000, max number of cicuit connections is 4", + "value": "Standard" + }, + { + "label": "HighPerformance", + "description": "Megabits per second 2000, packets per second 250,000, connections per second 14000, max number of cicuit connections is 8", + "value": "HighPerformance" + }, + { + "label": "UltraPerformance", + "description": "Megabits per second 10,000, packets per second 1,000,000, connections per second 28,000, max number of cicuit connections is 16", + "value": "UltraPerformance" + } + ] + } + }, + { + "name": "esErNoAzSku", + "type": "Microsoft.Common.DropDown", + "label": "Select the ExpressRoute Gateway SKU", + "defaultValue": "", + "multiselect": false, + "selectAll": false, + "filter": false, + "multiLine": true, + "visible": "[and(equals(steps('esConnectivityGoalState').esErGw,'Yes'), not(or(or(or(or(or(or(or(or(equals(steps('esConnectivityGoalState').esNwLocation,'canadacentral'),equals(steps('esConnectivityGoalState').esNwLocation,'centralus')),equals(steps('esConnectivityGoalState').esNwLocation,'eastus'),equals(steps('esConnectivityGoalState').esNwLocation,'eastus2')),equals(steps('esConnectivityGoalState').esNwLocation,'southcentralus'),equals(steps('esConnectivityGoalState').esNwLocation,'westus2')),equals(steps('esConnectivityGoalState').esNwLocation,'francecentral'),equals(steps('esConnectivityGoalState').esNwLocation,'germanywestcentral')),equals(steps('esConnectivityGoalState').esNwLocation,'northeurope'),equals(steps('esConnectivityGoalState').esNwLocation,'westeurope')),equals(steps('esConnectivityGoalState').esNwLocation,'uksouth'),equals(steps('esConnectivityGoalState').esNwLocation,'southafricanorth')),equals(steps('esConnectivityGoalState').esNwLocation,'japaneast'),equals(steps('esConnectivityGoalState').esNwLocation,'southeastasia')),equals(steps('esConnectivityGoalState').esNwLocation,'southeastasia'),equals(steps('esConnectivityGoalState').esNwLocation,'australiaeast'))))]", + "toolTip": "Select the required SKU for the Express Route gateway.", + "constraints": { + "allowedValues": [ + { + "label": "Standard", + "description": "Megabits per second 1000, packets per second 100,000, connections per second 7000, max number of cicuit connections is 4", + "value": "Standard" + }, + { + "label": "HighPerformance", + "description": "Megabits per second 2000, packets per second 250,000, connections per second 14000, max number of cicuit connections is 8", + "value": "HighPerformance" + }, + { + "label": "UltraPerformance", + "description": "Megabits per second 10,000, packets per second 1,000,000, connections per second 28,000, max number of cicuit connections is 16", + "value": "UltraPerformance" + } + ] + } + }, + { + "name": "esAzFw", + "type": "Microsoft.Common.OptionsGroup", + "label": "Deploy Azure Firewall", + "defaultValue": "No", + "visible": "[equals(steps('esConnectivityGoalState').esHub, 'Yes')]", + "toolTip": "If 'Yes' is selected when also adding a subscription for connectivity, ARM will deploy Azure Firewall", + "constraints": { + "allowedValues": [ + { + "label": "Yes (recommended)", + "value": "Yes" + }, + { + "label": "No", + "value": "No" + } + ] + } + }, + { + "name": "esAzFwDns", + "type": "Microsoft.Common.OptionsGroup", + "label": "Enable Azure Firewall as a DNS proxy", + "defaultValue": "No", + "visible": "[equals(steps('esConnectivityGoalState').esAzFw,'Yes')]", + "toolTip": "If 'Yes' is selected when also adding a subscription for connectivity, ARM will enable Azure Firewall as a DNS Proxy.", + "constraints": { + "allowedValues": [ + { + "label": "Yes", + "value": "Yes" + }, + { + "label": "No", + "value": "No" + } + ] + } + }, + { + "name": "esFwAz", + "type": "Microsoft.Common.DropDown", + "label": "Select Availability Zones for the Azure Firewall", + "defaultValue": "None", + "multiselect": true, + "selectAll": true, + "filter": true, + "visible": "[and(equals(steps('esConnectivityGoalState').esAzFw,'Yes'),or(or(or(or(or(or(or(or(equals(steps('esConnectivityGoalState').esNwLocation,'canadacentral'),equals(steps('esConnectivityGoalState').esNwLocation,'centralus')),equals(steps('esConnectivityGoalState').esNwLocation,'eastus'),equals(steps('esConnectivityGoalState').esNwLocation,'eastus2')),equals(steps('esConnectivityGoalState').esNwLocation,'southcentralus'),equals(steps('esConnectivityGoalState').esNwLocation,'westus2')),equals(steps('esConnectivityGoalState').esNwLocation,'francecentral'),equals(steps('esConnectivityGoalState').esNwLocation,'germanywestcentral')),equals(steps('esConnectivityGoalState').esNwLocation,'northeurope'),equals(steps('esConnectivityGoalState').esNwLocation,'westeurope')),equals(steps('esConnectivityGoalState').esNwLocation,'uksouth'),equals(steps('esConnectivityGoalState').esNwLocation,'southafricanorth')),equals(steps('esConnectivityGoalState').esNwLocation,'japaneast'),equals(steps('esConnectivityGoalState').esNwLocation,'southeastasia')),equals(steps('esConnectivityGoalState').esNwLocation,'southeastasia'),equals(steps('esConnectivityGoalState').esNwLocation,'australiaeast')))]", + "toolTip": "If 'Yes' is selected when also adding a subscription for connectivity, ARM will deploy Azure Firewall to the selected region and availability zones.", + "constraints": { + "required": true, + "allowedValues": [ + { + "label": "Zone 1", + "value": "1" + }, + { + "label": "Zone 2", + "value": "2" + }, + { + "label": "Zone 3", + "value": "3" + } + ] + } + }, + { + "name": "esAddressFw", + "type": "Microsoft.Common.TextBox", + "label": "Subnet for Azure Firewall", + "toolTip": "Provide address prefix in CIDR notation (e.g 10.100.0.0/24)", + "defaultValue": "10.100.0.0/24", + "visible": "[equals(steps('esConnectivityGoalState').esAzFw, 'Yes')]", + "constraints": { + "required": true, + "validationMessage": "The subnet network's address space, specified as one address prefixes in CIDR notation (e.g. 192.168.1.0/24)" + } } + ] + }, + { + "name": "lzGoalState", + "label": "Landing zone configuration", + "subLabel": { + "preValidation": "", + "postValidation": "" }, - { - "name": "esEncryptionInTransit", - "type": "Microsoft.Common.OptionsGroup", - "label": "Ensure encryption in transit is enabled for PaaS services", - "defaultValue": "Yes (recommended)", - "visible": true, - "toolTip": "If 'Yes' is selected then Azure Policy will ensure PaaS resources uses TLS and SSL.", - "constraints": { - "allowedValues": [ - { - "label": "Yes (recommended)", - "value": "Yes" - }, - { - "label": "No", - "value": "No" - } - ] - } - }, - { - "name": "esVmMonitoring", - "type": "Microsoft.Common.OptionsGroup", - "label": "Ensure Azure VMs (Windows & Linux) are being monitored", - "defaultValue": "Yes (recommended)", - "toolTip": "If 'Yes' is selected when also adding a subscription for management, ARM will deploy resources and enable them for continous compliance", - "constraints": { - "allowedValues": [ - { - "label": "Yes (recommended)", - "value": "Yes" - }, - { - "label": "No", - "value": "No" - } - ] + "bladeTitle": "lzGs", + "elements": [ + { + "name": "infoBox1", + "type": "Microsoft.Common.InfoBox", + "visible": true, + "options": { + "icon": "Info", + "text": "You can optionally provide subscriptions for your first 'Online' and 'Corp' landing zones and assign recommended policies that will ensure workloads will be secure, monitored, and protected according to best practices.", + "uri": "https://github.com/Azure/Enterprise-Scale/blob/main/docs/Deploy/ES-schema.md" + } }, - "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" - }, - { - "name": "esAzBackup", - "type": "Microsoft.Common.OptionsGroup", - "label": "Ensure Azure VMs (Windows & Linux) are enabled for Azure Backup", - "defaultValue": "Yes (recommended)", - "toolTip": "If 'Yes' is selected, Azure Policy will be assigned and enable Azure Backup on all VMs in the landing zones.", - "constraints": { - "allowedValues": [ - { - "label": "Yes (recommended)", - "value": "Yes" - }, - { - "label": "No", - "value": "No" + { + "name": "onlineText", + "type": "Microsoft.Common.TextBlock", + "visible": true, + "options": { + "text": "Select the subscriptions you want to use to host your Online landing zones.", + "link": { + "label": "Learn more", + "uri": "https://docs.microsoft.com/azure/azure-monitor/insights/solutions" } - ] + } }, - "visible": true - }, - { - "name": "esDenyRdp", - "type": "Microsoft.Common.OptionsGroup", - "label": "Prevent inbound RDP from internet", - "defaultValue": "Yes (recommended)", - "toolTip": "If 'Yes' is selected, Azure Policy will be assigned and prevent inbound RDP from internet", - "constraints": { - "allowedValues": [ - { - "label": "Yes (recommended)", - "value": "Yes" - }, - { - "label": "No", - "value": "No" - } - ] + { + "name": "lzOnlineSubsApi", + "type": "Microsoft.Solutions.ArmApiControl", + "request": { + "method": "GET", + "path": "subscriptions?api-version=2020-01-01" + } }, - "visible": true - }, - { - "name": "esNsg", - "type": "Microsoft.Common.OptionsGroup", - "label": "Ensure subnets are associated with NSG", - "defaultValue": "Yes (recommended)", - "toolTip": "If 'Yes' is selected, Azure Policy will be assigned to ensure NSGs must be associated with subnets being created", - "constraints": { - "allowedValues": [ - { - "label": "Yes (recommended)", - "value": "Yes" - }, - { - "label": "No", - "value": "No" - } - ] + { + "name": "esOnlineLzSub", + "type": "Microsoft.Common.DropDown", + "label": "Online landing zone subscriptions (optional)", + "toolTip": "", + "multiselect": true, + "selectAll": true, + "filter": true, + "filterPlaceholder": "Filter items ...", + "multiLine": true, + "visible": true, + "constraints": { + "allowedValues": "[map(steps('lzGoalState').lzOnlineSubsApi.value, (sub) => parse(concat('{\"label\":\"', sub.displayName, '\",\"description\":\"', sub.subscriptionId, '\",\"value\":\"', toLower(sub.subscriptionId), '\"}')) )]", + "required": false + } }, - "visible": true - }, - { - "name": "esIpForwarding", - "type": "Microsoft.Common.OptionsGroup", - "label": "Prevent IP forwarding", - "defaultValue": "Yes (recommended)", - "toolTip": "If 'Yes' is selected, Azure Policy will be assigned and prevent IP forwarding", - "constraints": { - "allowedValues": [ - { - "label": "Yes (recommended)", - "value": "Yes" - }, - { - "label": "No", - "value": "No" + { + "name": "corpText", + "type": "Microsoft.Common.TextBlock", + "visible": true, + "options": { + "text": "Select the subscriptions you want to use to host your Corp landing zones.", + "link": { + "label": "Learn more", + "uri": "https://docs.microsoft.com/azure/azure-monitor/insights/solutions" } - ] + } }, - "visible": true - }, - { - "name": "esSqlEncryption", - "type": "Microsoft.Common.OptionsGroup", - "label": "Ensure Azure SQL is enabled with transparent data encryption", - "defaultValue": "Yes (recommended)", - "toolTip": "If 'Yes' is selected when also adding a subscription for management, ARM will deploy resources and enable them for continous compliance", - "constraints": { - "allowedValues": [ - { - "label": "Yes (recommended)", - "value": "Yes" - }, - { - "label": "No", - "value": "No" - } - ] + { + "name": "lzCorpSubsApi", + "type": "Microsoft.Solutions.ArmApiControl", + "request": { + "method": "GET", + "path": "subscriptions?api-version=2020-01-01" + } }, - "visible": true - }, - { - "name": "esSqlAudit", - "type": "Microsoft.Common.OptionsGroup", - "label": "Ensure auditing is enabled on Azure SQL", - "defaultValue": "Yes (recommended)", - "toolTip": "If 'Yes' is selected, Azure Policy will be assigned to ensure auditing is enabled on Azure SQLs", - "constraints": { - "allowedValues": [ - { - "label": "Yes (recommended)", - "value": "Yes" - }, - { - "label": "No", - "value": "No" - } - ] + { + "name": "esCorpLzSub", + "type": "Microsoft.Common.DropDown", + "label": "Corp landing zone subscriptions (optional)", + "toolTip": "", + "multiselect": true, + "selectAll": true, + "filter": true, + "filterPlaceholder": "Filter items ...", + "multiLine": true, + "visible": true, + "constraints": { + "allowedValues": "[map(steps('lzGoalState').lzCorpSubsApi.value, (sub) => parse(concat('{\"label\":\"', sub.displayName, '\",\"description\":\"', sub.subscriptionId, '\",\"value\":\"', toLower(sub.subscriptionId), '\"}')) )]", + "required": false + } }, - "visible": true - }, - { - "name": "esHttpsStorage", - "type": "Microsoft.Common.OptionsGroup", - "label": "Ensure secure connections (HTTPS) to storage accounts", - "defaultValue": "Yes (recommended)", - "toolTip": "If 'Yes' is selected, Azure Policy will be assigned to ensure storage can only be accessed using HTTPS", - "constraints": { - "allowedValues": [ - { - "label": "Yes (recommended)", - "value": "Yes" - }, - { - "label": "No", - "value": "No" + { + "name": "azMonText", + "type": "Microsoft.Common.TextBlock", + "visible": true, + "options": { + "text": "Select which of the the recommended policies you will assign to all your landing zones. That includes Online, Corp and additional Landing Zone's types you may add in the future.", + "link": { + "label": "Learn more", + "uri": "https://docs.microsoft.com/en-us/azure/cloud-adoption-framework/ready/enterprise-scale/design-principles#policy-driven-governance" } - ] + } + }, + { + "name": "esLzDdoS", + "type": "Microsoft.Common.OptionsGroup", + "label": "Enable DDoS Protection Standard", + "defaultValue": "No", + "visible": "[and(equals(steps('esConnectivityGoalState').esHub,'Yes'),equals(steps('esConnectivityGoalState').esDdoS,'Yes'))]", + "toolTip": "If 'Yes' is selected when also adding a connectivity subscription earlier, DDoS Protection Standard will be enabled.", + "constraints": { + "allowedValues": [ + { + "label": "Yes (recommended)", + "value": "Yes" + }, + { + "label": "No", + "value": "No" + } + ] + } + }, + { + "name": "esLzPrivateLink", + "type": "Microsoft.Common.OptionsGroup", + "label": "Prevent usage of Public Endpoints for PaaS services in the corp connected landing zones", + "defaultValue": "Yes (recommended)", + "visible": true, + "toolTip": "If 'Yes' is selected then Azure Policy will prevent PaaS resources to use public endpoints.", + "constraints": { + "allowedValues": [ + { + "label": "Yes (recommended)", + "value": "Yes" + }, + { + "label": "No", + "value": "No" + } + ] + } + }, + { + "name": "esEncryptionInTransit", + "type": "Microsoft.Common.OptionsGroup", + "label": "Ensure encryption in transit is enabled for PaaS services", + "defaultValue": "Yes (recommended)", + "visible": true, + "toolTip": "If 'Yes' is selected then Azure Policy will ensure PaaS resources uses TLS and SSL.", + "constraints": { + "allowedValues": [ + { + "label": "Yes (recommended)", + "value": "Yes" + }, + { + "label": "No", + "value": "No" + } + ] + } }, - "visible": true - } - ] - } - ] - }, + { + "name": "esVmMonitoring", + "type": "Microsoft.Common.OptionsGroup", + "label": "Ensure Azure VMs (Windows & Linux) are being monitored", + "defaultValue": "Yes (recommended)", + "toolTip": "If 'Yes' is selected when also adding a subscription for management, ARM will deploy resources and enable them for continous compliance", + "constraints": { + "allowedValues": [ + { + "label": "Yes (recommended)", + "value": "Yes" + }, + { + "label": "No", + "value": "No" + } + ] + }, + "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" + }, + { + "name": "esAzBackup", + "type": "Microsoft.Common.OptionsGroup", + "label": "Ensure Azure VMs (Windows & Linux) are enabled for Azure Backup", + "defaultValue": "Yes (recommended)", + "toolTip": "If 'Yes' is selected, Azure Policy will be assigned and enable Azure Backup on all VMs in the landing zones.", + "constraints": { + "allowedValues": [ + { + "label": "Yes (recommended)", + "value": "Yes" + }, + { + "label": "No", + "value": "No" + } + ] + }, + "visible": true + }, + { + "name": "esDenyRdp", + "type": "Microsoft.Common.OptionsGroup", + "label": "Prevent inbound RDP from internet", + "defaultValue": "Yes (recommended)", + "toolTip": "If 'Yes' is selected, Azure Policy will be assigned and prevent inbound RDP from internet", + "constraints": { + "allowedValues": [ + { + "label": "Yes (recommended)", + "value": "Yes" + }, + { + "label": "No", + "value": "No" + } + ] + }, + "visible": true + }, + { + "name": "esNsg", + "type": "Microsoft.Common.OptionsGroup", + "label": "Ensure subnets are associated with NSG", + "defaultValue": "Yes (recommended)", + "toolTip": "If 'Yes' is selected, Azure Policy will be assigned to ensure NSGs must be associated with subnets being created", + "constraints": { + "allowedValues": [ + { + "label": "Yes (recommended)", + "value": "Yes" + }, + { + "label": "No", + "value": "No" + } + ] + }, + "visible": true + }, + { + "name": "esIpForwarding", + "type": "Microsoft.Common.OptionsGroup", + "label": "Prevent IP forwarding", + "defaultValue": "Yes (recommended)", + "toolTip": "If 'Yes' is selected, Azure Policy will be assigned and prevent IP forwarding", + "constraints": { + "allowedValues": [ + { + "label": "Yes (recommended)", + "value": "Yes" + }, + { + "label": "No", + "value": "No" + } + ] + }, + "visible": true + }, + { + "name": "esSqlEncryption", + "type": "Microsoft.Common.OptionsGroup", + "label": "Ensure Azure SQL is enabled with transparent data encryption", + "defaultValue": "Yes (recommended)", + "toolTip": "If 'Yes' is selected when also adding a subscription for management, ARM will deploy resources and enable them for continous compliance", + "constraints": { + "allowedValues": [ + { + "label": "Yes (recommended)", + "value": "Yes" + }, + { + "label": "No", + "value": "No" + } + ] + }, + "visible": true + }, + { + "name": "esSqlAudit", + "type": "Microsoft.Common.OptionsGroup", + "label": "Ensure auditing is enabled on Azure SQL", + "defaultValue": "Yes (recommended)", + "toolTip": "If 'Yes' is selected, Azure Policy will be assigned to ensure auditing is enabled on Azure SQLs", + "constraints": { + "allowedValues": [ + { + "label": "Yes (recommended)", + "value": "Yes" + }, + { + "label": "No", + "value": "No" + } + ] + }, + "visible": true + }, + { + "name": "esHttpsStorage", + "type": "Microsoft.Common.OptionsGroup", + "label": "Ensure secure connections (HTTPS) to storage accounts", + "defaultValue": "Yes (recommended)", + "toolTip": "If 'Yes' is selected, Azure Policy will be assigned to ensure storage can only be accessed using HTTPS", + "constraints": { + "allowedValues": [ + { + "label": "Yes (recommended)", + "value": "Yes" + }, + { + "label": "No", + "value": "No" + } + ] + }, + "visible": true + } + ] + } + ] + }, "outputs": { "parameters": { - "enterpriseScaleCompanyPrefix": "[steps('lzSettings').esMgmtGroup]", - "platformSubscriptionId": "[if(not(empty(steps('esGoalState').esMgmtSub)), steps('esGoalState').esMgmtSub, if(not(empty(steps('esConnectivityGoalState').esConnectivitySub)), steps('esConnectivityGoalState').esConnectivitySub, ''))]", - "enableLogAnalytics": "[steps('esGoalState').esLogAnalytics]", - "retentionInDays": "[string(steps('esGoalState').esLogRetention)]", - "enableAgentHealth": "[steps('esGoalState').esAgentSolution]", - "enableChangeTracking": "[steps('esGoalState').esChangeTracking]", - "enableUpdateMgmt": "[steps('esGoalState').esUpdateMgmt]", - "enableActivityLog": "[steps('esGoalState').esActivityLog]", - "enableVmInsights": "[steps('esGoalState').esVmInsights]", - "enableAntiMalware": "[steps('esGoalState').esAntiMalware]", - "enableServiceMap": "[steps('esGoalState').esServiceMap]", - "enableSqlAssessment": "[steps('esGoalState').esSqlAssessment]", - "enableAsc": "[steps('esGoalState').esAsc]", - "emailContactAsc": "[steps('esGoalState').esAscEmail]", - "enableSecuritySolution": "[steps('esGoalState').esSecuritySolution]", - "location": "[steps('esConnectivityGoalState').esNwLocation]", - "vpnGwType": "[steps('esConnectivityGoalState').esVpnGwType]", - "subnetMaskForGw": "[steps('esConnectivityGoalState').esAddressVpnOrEr]", - "subnetMaskForAzFw": "[steps('esConnectivityGoalState').esAddressFw]", - "enableErGw": "[steps('esConnectivityGoalState').esErGw]", - "enableVpnGw": "[steps('esConnectivityGoalState').esVpnGw]", - "enableHub": "[steps('esConnectivityGoalState').esHub]", - "enableDdoS": "[steps('esConnectivityGoalState').esDdoS]", - "enableAzFw": "[steps('esConnectivityGoalState').esAzFw]", - "enableAzFwDnsProxy": "[steps('esConnectivityGoalState').esAzFwDns]", - "addressPrefix": "[steps('esConnectivityGoalState').esAddressHub]", - "enableLzDdoS": "[steps('lzGoalState').esLzDdoS]", - "denyPublicEndpoints": "[steps('lzGoalState').esLzPrivateLink]", - "enableEncryptionInTransit": "[steps('lzGoalState').esEncryptionInTransit]", - "onlineLzSubscriptionId": "[if(not(contains(steps('lzGoalState').esOnlineLzSub,if(not(empty(steps('esGoalState').esMgmtSub)), steps('esGoalState').esMgmtSub, if(not(empty(steps('esConnectivityGoalState').esConnectivitySub)), steps('esConnectivityGoalState').esConnectivitySub, '')))),steps('lzGoalState').esOnlineLzSub,'')]", - "corpLzSubscriptionId": "[if(not(contains(steps('lzGoalState').esCorpLzSub,if(not(empty(steps('esGoalState').esMgmtSub)), steps('esGoalState').esMgmtSub, if(not(empty(steps('esConnectivityGoalState').esConnectivitySub)), steps('esConnectivityGoalState').esConnectivitySub, '')))),steps('lzGoalState').esCorpLzSub,'')]", - "enableSqlAudit": "[steps('lzGoalState').esSqlAudit]", - "enableSqlEncryption": "[steps('lzGoalState').esSqlEncryption]", - "enableVmBackup": "[steps('lzGoalState').esAzBackup]", - "denyRdp": "[steps('lzGoalState').esDenyRdp]", - "enableStorageHttps": "[steps('lzGoalState').esHttpsStorage]", - "denyIpForwarding": "[steps('lzGoalState').esIpForwarding]", - "denySubnetWithoutNsg": "[steps('lzGoalState').esNsg]", - "enableVmMonitoring": "[steps('lzGoalState').esVmMonitoring]", - "vpnOrErZones": "[steps('esConnectivityGoalState').esGwRegionalOrAz]", - "firewallZones": "[steps('esConnectivityGoalState').esFwAz]", - "gwRegionalOrAz": "[steps('esConnectivityGoalState').esGwRegionalOrAz]", - "gwAzSku": "[steps('esConnectivityGoalState').esGwAzSku]", - "gwRegionalSku": "[if(empty(steps('esConnectivityGoalState').esGwRegionalSku), steps('esConnectivityGoalState').esGwNoAzSku, steps('esConnectivityGoalState').esGwRegionalSku)]", - "erRegionalOrAz": "[steps('esConnectivityGoalState').esErRegionalOrAz]", - "erAzSku": "[steps('esConnectivityGoalState').esErAzSku]", - "erRegionalSku": "[if(empty(steps('esConnectivityGoalState').esErRegionalSku), steps('esConnectivityGoalState').esErNoAzSku, steps('esConnectivityGoalState').esErRegionalSku)]", - "enableAksPolicy": "No", - "denyAksPrivileged": "No", - "denyAksPrivilegedEscalation": "No", - "denyHttpIngressForAks": "No", - "enableVmssMonitoring": "No", - "enableArcMonitoring": "No" + "enterpriseScaleCompanyPrefix": "[steps('lzSettings').esMgmtGroup]", + "platformSubscriptionId": "[if(not(empty(steps('esGoalState').esMgmtSub)), steps('esGoalState').esMgmtSub, if(not(empty(steps('esConnectivityGoalState').esConnectivitySub)), steps('esConnectivityGoalState').esConnectivitySub, ''))]", + "enableLogAnalytics": "[steps('esGoalState').esLogAnalytics]", + "retentionInDays": "[string(steps('esGoalState').esLogRetention)]", + "enableAgentHealth": "[steps('esGoalState').esAgentSolution]", + "enableChangeTracking": "[steps('esGoalState').esChangeTracking]", + "enableUpdateMgmt": "[steps('esGoalState').esUpdateMgmt]", + "enableVmInsights": "[steps('esGoalState').esVmInsights]", + "enableAntiMalware": "[steps('esGoalState').esAntiMalware]", + "enableServiceMap": "[steps('esGoalState').esServiceMap]", + "enableSqlAssessment": "[steps('esGoalState').esSqlAssessment]", + "enableAsc": "[steps('esGoalState').esAsc]", + "emailContactAsc": "[steps('esGoalState').esAscEmail]", + "enableSecuritySolution": "[steps('esGoalState').esSecuritySolution]", + "location": "[steps('esConnectivityGoalState').esNwLocation]", + "vpnGwType": "[steps('esConnectivityGoalState').esVpnGwType]", + "subnetMaskForGw": "[steps('esConnectivityGoalState').esAddressVpnOrEr]", + "subnetMaskForAzFw": "[steps('esConnectivityGoalState').esAddressFw]", + "enableErGw": "[steps('esConnectivityGoalState').esErGw]", + "enableVpnGw": "[steps('esConnectivityGoalState').esVpnGw]", + "enableHub": "[steps('esConnectivityGoalState').esHub]", + "enableDdoS": "[steps('esConnectivityGoalState').esDdoS]", + "enableAzFw": "[steps('esConnectivityGoalState').esAzFw]", + "enableAzFwDnsProxy": "[steps('esConnectivityGoalState').esAzFwDns]", + "addressPrefix": "[steps('esConnectivityGoalState').esAddressHub]", + "enableLzDdoS": "[steps('lzGoalState').esLzDdoS]", + "denyPublicEndpoints": "[steps('lzGoalState').esLzPrivateLink]", + "enableEncryptionInTransit": "[steps('lzGoalState').esEncryptionInTransit]", + "onlineLzSubscriptionId": "[if(not(contains(steps('lzGoalState').esOnlineLzSub,if(not(empty(steps('esGoalState').esMgmtSub)), steps('esGoalState').esMgmtSub, if(not(empty(steps('esConnectivityGoalState').esConnectivitySub)), steps('esConnectivityGoalState').esConnectivitySub, '')))),steps('lzGoalState').esOnlineLzSub,'')]", + "corpLzSubscriptionId": "[if(not(contains(steps('lzGoalState').esCorpLzSub,if(not(empty(steps('esGoalState').esMgmtSub)), steps('esGoalState').esMgmtSub, if(not(empty(steps('esConnectivityGoalState').esConnectivitySub)), steps('esConnectivityGoalState').esConnectivitySub, '')))),steps('lzGoalState').esCorpLzSub,'')]", + "enableSqlAudit": "[steps('lzGoalState').esSqlAudit]", + "enableSqlEncryption": "[steps('lzGoalState').esSqlEncryption]", + "enableVmBackup": "[steps('lzGoalState').esAzBackup]", + "denyRdp": "[steps('lzGoalState').esDenyRdp]", + "enableStorageHttps": "[steps('lzGoalState').esHttpsStorage]", + "denyIpForwarding": "[steps('lzGoalState').esIpForwarding]", + "denySubnetWithoutNsg": "[steps('lzGoalState').esNsg]", + "enableVmMonitoring": "[steps('lzGoalState').esVmMonitoring]", + "vpnOrErZones": "[steps('esConnectivityGoalState').esGwRegionalOrAz]", + "firewallZones": "[steps('esConnectivityGoalState').esFwAz]", + "gwRegionalOrAz": "[steps('esConnectivityGoalState').esGwRegionalOrAz]", + "gwAzSku": "[steps('esConnectivityGoalState').esGwAzSku]", + "gwRegionalSku": "[if(empty(steps('esConnectivityGoalState').esGwRegionalSku), steps('esConnectivityGoalState').esGwNoAzSku, steps('esConnectivityGoalState').esGwRegionalSku)]", + "erRegionalOrAz": "[steps('esConnectivityGoalState').esErRegionalOrAz]", + "erAzSku": "[steps('esConnectivityGoalState').esErAzSku]", + "erRegionalSku": "[if(empty(steps('esConnectivityGoalState').esErRegionalSku), steps('esConnectivityGoalState').esErNoAzSku, steps('esConnectivityGoalState').esErRegionalSku)]", + "enableAksPolicy": "No", + "denyAksPrivileged": "No", + "denyAksPrivilegedEscalation": "No", + "denyHttpIngressForAks": "No", + "enableVmssMonitoring": "No", + "enableArcMonitoring": "No" }, "kind": "Tenant", "location": "[steps('basics').resourceScope.location.name]" diff --git a/docs/reference/treyresearch/armTemplates/portal-es-lite.json b/docs/reference/treyresearch/armTemplates/portal-es-lite.json index d6eda54196..cc28b9e4a8 100644 --- a/docs/reference/treyresearch/armTemplates/portal-es-lite.json +++ b/docs/reference/treyresearch/armTemplates/portal-es-lite.json @@ -104,7 +104,7 @@ "required": false }, "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" - }, + }, { "name": "mgmtSubsApi", "type": "Microsoft.Solutions.ArmApiControl", @@ -128,7 +128,7 @@ "allowedValues": "[map(steps('esGoalState').mgmtSubsApi.value, (sub) => parse(concat('{\"label\":\"', sub.displayName, '\",\"description\":\"', sub.subscriptionId, '\",\"value\":\"', toLower(sub.subscriptionId), '\"}')) )]", "required": true } - }, + }, { "name": "textBlock1", "type": "Microsoft.Common.TextBlock", @@ -159,8 +159,8 @@ } ] }, - "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" - }, + "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" + }, { "name": "esChangeTracking", "type": "Microsoft.Common.OptionsGroup", @@ -179,7 +179,7 @@ } ] }, - "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" + "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" }, { "name": "esUpdateMgmt", @@ -199,27 +199,7 @@ } ] }, - "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" - }, - { - "name": "esActivityLog", - "type": "Microsoft.Common.OptionsGroup", - "label": "Deploy Activity Log solution", - "defaultValue": "Yes (recommended)", - "toolTip": "If 'Yes' is selected when also adding a subscription for management, ARM will deploy resources and enable them for continous compliance", - "constraints": { - "allowedValues": [ - { - "label": "Yes (recommended)", - "value": "Yes" - }, - { - "label": "No", - "value": "No" - } - ] - }, - "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" + "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" }, { "name": "esVmInsights", @@ -239,7 +219,7 @@ } ] }, - "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" + "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" }, { "name": "esAntiMalware", @@ -259,7 +239,7 @@ } ] }, - "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" + "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" }, { "name": "esServiceMap", @@ -279,7 +259,7 @@ } ] }, - "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" + "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" }, { "name": "esSqlAssessment", @@ -299,12 +279,12 @@ } ] }, - "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" + "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" }, { "name": "textBlock0", "type": "Microsoft.Common.TextBlock", - "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]", + "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]", "options": { "text": "Select which Azure Security solutions you will enable.", "link": { @@ -312,7 +292,7 @@ "uri": "https://docs.microsoft.com/azure/security/fundamentals/overview" } } - }, + }, { "name": "esAsc", "type": "Microsoft.Common.OptionsGroup", @@ -335,7 +315,7 @@ } ] }, - "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" + "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" }, { "name": "esAscEmail", @@ -349,7 +329,7 @@ "regex": "^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$", "validationMessage": "Please provide a valid email address" } - }, + }, { "name": "esSecuritySolution", "type": "Microsoft.Common.OptionsGroup", @@ -368,8 +348,8 @@ } ] }, - "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" - } + "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" + } ] }, { @@ -448,7 +428,7 @@ "validationMessage": "The virtual hubs network's address space, specified as one address prefixes in CIDR notation (e.g. 192.168.1.0/24)" } }, - { + { "name": "esLocationsApi", "type": "Microsoft.Solutions.ArmApiControl", "request": { @@ -894,7 +874,7 @@ } } ] - }, + }, { "name": "lzGoalState", "label": "Landing zone configuration", @@ -985,7 +965,7 @@ "allowedValues": "[map(steps('lzGoalState').lzCorpSubsApi.value, (sub) => parse(concat('{\"label\":\"', sub.displayName, '\",\"description\":\"', sub.subscriptionId, '\",\"value\":\"', toLower(sub.subscriptionId), '\"}')) )]", "required": false } - }, + }, { "name": "azMonText", "type": "Microsoft.Common.TextBlock", @@ -1057,7 +1037,7 @@ } ] } - }, + }, { "name": "esVmMonitoring", "type": "Microsoft.Common.OptionsGroup", @@ -1076,8 +1056,8 @@ } ] }, - "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" - }, + "visible": "[equals(steps('esGoalState').esLogAnalytics, 'Yes')]" + }, { "name": "esAzBackup", "type": "Microsoft.Common.OptionsGroup", @@ -1225,19 +1205,18 @@ "enterpriseScaleCompanyPrefix": "[steps('lzSettings').esMgmtGroup]", "platformSubscriptionId": "[if(not(empty(steps('esGoalState').esMgmtSub)), steps('esGoalState').esMgmtSub, if(not(empty(steps('esConnectivityGoalState').esConnectivitySub)), steps('esConnectivityGoalState').esConnectivitySub, ''))]", "enableLogAnalytics": "[steps('esGoalState').esLogAnalytics]", - "retentionInDays": "[string(steps('esGoalState').esLogRetention)]", + "retentionInDays": "[string(steps('esGoalState').esLogRetention)]", "enableAgentHealth": "[steps('esGoalState').esAgentSolution]", "enableChangeTracking": "[steps('esGoalState').esChangeTracking]", "enableUpdateMgmt": "[steps('esGoalState').esUpdateMgmt]", - "enableActivityLog": "[steps('esGoalState').esActivityLog]", "enableVmInsights": "[steps('esGoalState').esVmInsights]", "enableAntiMalware": "[steps('esGoalState').esAntiMalware]", "enableServiceMap": "[steps('esGoalState').esServiceMap]", "enableSqlAssessment": "[steps('esGoalState').esSqlAssessment]", "enableAsc": "[steps('esGoalState').esAsc]", - "emailContactAsc": "[steps('esGoalState').esAscEmail]", + "emailContactAsc": "[steps('esGoalState').esAscEmail]", "enableSecuritySolution": "[steps('esGoalState').esSecuritySolution]", - "location": "[steps('esConnectivityGoalState').esNwLocation]", + "location": "[steps('esConnectivityGoalState').esNwLocation]", "vpnGwType": "[steps('esConnectivityGoalState').esVpnGwType]", "subnetMaskForGw": "[steps('esConnectivityGoalState').esAddressVpnOrEr]", "subnetMaskForAzFw": "[steps('esConnectivityGoalState').esAddressFw]", diff --git a/docs/reference/wingtip/README.md b/docs/reference/wingtip/README.md index 0475ace53e..c38f9aa2a6 100644 --- a/docs/reference/wingtip/README.md +++ b/docs/reference/wingtip/README.md @@ -1,6 +1,6 @@ | ARM Template | Scale without refactoring | |:--------------|:--------------| -|[![Deploy To Azure](https://docs.microsoft.com/en-us/azure/templates/media/deploy-to-azure.svg)](https://portal.azure.com/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2FeslzArm%2FeslzArm.json/uiFormDefinitionUri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2FeslzArm%2Feslz-portal.json) | Yes | +|[![Deploy To Azure](https://docs.microsoft.com/azure/templates/media/deploy-to-azure.svg)](https://portal.azure.com/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2FeslzArm%2FeslzArm.json/uiFormDefinitionUri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2FeslzArm%2Feslz-portal.json) | Yes | # Deploy Enterprise-Scale foundation diff --git a/docs/wiki/ALZ-Architecture.md b/docs/wiki/ALZ-Architecture.md new file mode 100644 index 0000000000..53d0deabd4 --- /dev/null +++ b/docs/wiki/ALZ-Architecture.md @@ -0,0 +1,53 @@ + +# Enterprise-Scale Architecture + +The principle challenges facing enterprise customers adopting Azure are 1) how to allow applications (legacy or modern) to seamlessly move at their own pace, and 2) how to provide secure and streamlined operations, management, and governance across the entire platform and all encompassed applications. To address these challenges, customers require a forward looking and Azure-native design approach, which in the context of this playbook is represented by the Enterprise-Scale architecture. + +## What is the Enterprise-Scale Architecture + +The Enterprise-Scale architecture represents the strategic design path and target technical state for the customer's Azure environment. It will continue to evolve in lockstep with the Azure platform and is ultimately defined by the various design decisions the customer organization must make to define their Azure journey. + +It is important to highlight that not all enterprises adopt Azure in the same way, and as a result the Enterprise-Scale architecture may vary between customers. Ultimately, the technical considerations and design recommendations presented within this playbook may yield different trade-offs based on the customer scenario. Some variation is therefore expected, but provided core recommendations are followed, the resultant target architecture will position the customer on a path to sustainable scale. + +## Landing Zones Definition + +Within the context of the Enterprise-Scale architecture, a "Landing Zone" is a logical construct capturing everything that must be true to enable application migrations and development at an Enterprise-Scale in Azure. It considers all platform Resources that are required to support the customer's application portfolio and does not differentiate between IaaS or PaaS. + +Every large enterprise software estate will encompass a myriad of application archetypes and each Landing Zone essentially represents the common elements, such as networking and IAM, that are shared across instances of these archetypes and must be in place to ensure that migrating applications have access to requisite components when deployed. Each Landing Zone must consequently be designed and deployed in accordance with the requirements of archetypes within the customer's application portfolio. + +The principle purpose of the "Landing Zones" is therefore to ensure that when an application lands on Azure, the required "plumbing" is already in place, providing greater agility and compliance with enterprise security and governance requirements. + +--- + +_Using an analogy, this is similar to how city utilities such as water, gas, and electricity are accessible before new houses are constructed. In this context, the network, IAM, policies, management, and monitoring are shared 'utility' services that must be readily available to help streamline the application migration process._ + +--- + +# Design Principles + +The Enterprise-Scale architecture is based on the [five design principles](https://docs.microsoft.com/azure/cloud-adoption-framework/ready/enterprise-scale/design-principles). These principles serve as a compass for subsequent design decisions across critical technical domains. Readers and users of the reference implementation are strongly advised to familiarize themselves with these principles to better understand their impact and the trade-offs associated with non-adherence. + +* [Subscription democratization](https://docs.microsoft.com/azure/cloud-adoption-framework/ready/enterprise-scale/design-principles?branch#subscription-democratization) +* [Policy-driven governance](https://docs.microsoft.com/azure/cloud-adoption-framework/ready/enterprise-scale/design-principles#policy-driven-governance) +* [Single control and management plane](https://docs.microsoft.com/azure/cloud-adoption-framework/ready/enterprise-scale/design-principles#single-control-and-management-plane) +* [Application-centric service model](https://docs.microsoft.com/azure/cloud-adoption-framework/ready/enterprise-scale/design-principles?#application-centric-service-model) +* [Align with Azure-native design and roadmaps](https://docs.microsoft.com/azure/cloud-adoption-framework/ready/enterprise-scale/design-principles#align-with-azure-native-design-and-roadmaps) + +# Design Guidelines + +At the centre of the Enterprise-Scale architecture lies a critical design path, comprised of fundamental design topics with heavily interrelated and dependent design decisions. This repository provides design guidance across these architecturally significant technical domains to support the critical design decisions which must occur to define the Enterprise-Scale architecture. For each of the considered domains, readers should review the provided considerations and recommendations, using them to structure and drive designs within each area. + +## Critical Design Areas + +The [eight critical design areas](https://docs.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-areas) are intended to support the translation of customer requirements to Azure constructs and capabilities, to address the mismatch between on-premises infrastructure and cloud-design which typically creates dissonance and friction with respect to the Enterprise-Scale definition and Azure adoption. + +The impact of decisions made within these critical areas will reverberate across the Enterprise-Scale architecture and influence other decisions. Readers and reference implementation users are strongly advised to familiarize themselves with these eight areas, to better understand the consequences of encompassed decisions, which may later produce trade-offs within related areas. + +* [Billing and Active Directory tenants](https://docs.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-ad-tenant) +* [Identity and access management](https://docs.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/identity-access) +* [Network topology and connectivity](https://docs.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/network-topology-and-connectivity) +* [Resource organization](https://docs.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/resource-org) +* [Security](https://docs.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/security) +* [Management](https://docs.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/management) +* [Governance](https://docs.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/governance) +* [Platform automation and DevOps](https://docs.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/platform-automation-devops) diff --git a/docs/wiki/ALZ-Contribution-Guide.md b/docs/wiki/ALZ-Contribution-Guide.md new file mode 100644 index 0000000000..b0069d5a9d --- /dev/null +++ b/docs/wiki/ALZ-Contribution-Guide.md @@ -0,0 +1,175 @@ +# Contributing to Azure landing zones (Enterprise-Scale) + +Firstly, thank you for taking the time to contribute! + +The Azure landing zone reference implementations are designed to help customers accelerate their cloud adoption journey. +By contributing, you can help our community get the best out of these reference implementations. + +We actively encourage community contributions as we realize the unique and diverse requirements of our customers can help drive a better outcome for everyone. + +## What are the reference implementations + +To meet the diverse needs of our community, we offer the following reference implementation options: + +- [ALZ ARM portal experience (this repository)](https://github.com/Azure/Enterprise-Scale) +- [ALZ Bicep modules](https://github.com/Azure/ALZ-Bicep) +- [ALZ Terraform module](https://github.com/Azure/terraform-azurerm-caf-enterprise-scale) + +Whilst each reference implementation is uniquely characterized by its target community, they all aim to deliver against the Azure landing zone [conceptual architecture](https://docs.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/#azure-landing-zone-conceptual-architecture), [design principles](https://docs.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-principles) and [design areas](https://docs.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-areas). + +The following is a set of general guidelines for contributing to any of these reference implementations. + +## How do we manage contributions + +Contributions to each Azure landing zone reference implementation option is moderated by a common committee of maintainers. +The committee is responsible for reviewing and approving all contributions, whether via [**GitHub Issues**](https://github.com/Azure/Enterprise-Scale/issues), [**Pull Requests**](https://github.com/Azure/Enterprise-Scale/pulls), or internally driven development. + +The committee is also responsible for reviewing and sponsoring new features or design changes to ensure they meet the needs of our broad community of consumers. + +The intent of this approach is to ensures that each reference implementation continues to deliver against the Azure landing zone [conceptual architecture](https://docs.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/#azure-landing-zone-conceptual-architecture), [design principles](https://docs.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-principles) and [design areas](https://docs.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-areas). +This also helps us to drive towards consistency across the reference implementation options, where possible. + +The committee currently consists of Microsoft employees only. +It is expected that over time, community contributions will grow and new community members will join as committee members. +Membership is heavily dependent on the level of contribution and expertise: individuals who contribute in meaningful ways to the project will be recognized accordingly. + +At any point in time, a committee member can nominate a strong community member to join the committee. +Nominations should be submitted in the form of RFCs detailing why that individual is qualified and how they will contribute. +After the RFC has been discussed, a unanimous vote will be required for the new committee member to be confirmed. + +## How can I contribute? + +As an open source project, the reference implementation works best when it reflects the needs of our community of consumers. +As such, we welcome contributions however big or small. +All we ask is that you follow some simple guidelines, including participating according to our [**code of conduct**](https://github.com/Azure/Enterprise-Scale/blob/main/CODE_OF_CONDUCT.md). + +### Reporting bugs + +Like all software solutions, the Azure landing zone reference implementation isn't free from bugs. +Moreover, as the Azure platform evolves or our guidance changes there will likely be a need to make updates. + +If you believe you have found a bug, please use the following process: + +1. Check the [**FAQ**](./FAQ) and [**Known Issues**](https://github.com/Azure/Enterprise-Scale/blob/main/docs/wiki/ALZ-Known-Issues) for a list of common questions and issues. +1. Check existing [**GitHub Issues**](https://github.com/Azure/Enterprise-Scale/issues) to see whether the issue has already been reported. + 1. If the issue is **open**, add a comment rather than create a new one. + 1. If the issue is **closed**, check whether the proposed fix resolves your issue. +1. Report it via our [**GitHub Issues**](https://github.com/Azure/Enterprise-Scale/issues). +1. Select `New issue` and use the `Bug report 🐛` template +1. Ensure you fill out the template with as much information as possible, being sure to cover off what's needed for maintainers and the community to: + 1. Understand your issue :memo: + 1. Reproduce the behavior :computer: + 1. Provide evidence :mag_right: + 1. Optionally, let us know if you would like to contribute a fix via a [**Pull Request**](https://github.com/Azure/Enterprise-Scale/pulls) :wrench: + +### Feature requests + +We understand that our solutions are going to always be a work in progress, and that customers will need and want to request new features. +This is where you can really make a difference to how the solution is shaped for our community. + +If you have an idea you would like to be considered for inclusion, please use the following process: + +1. Familiarize yourself with our [conceptual architecture](https://docs.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/#azure-landing-zone-conceptual-architecture), [design principles](https://docs.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-principles) and [design areas](https://docs.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-areas) to ensure the feature aligns with the Azure landing zone guidance. +1. Check existing [**GitHub Issues**](https://github.com/Azure/Enterprise-Scale/issues) to see whether the issue has already been reported. + 1. If the issue is **open**, add a comment rather than create a new one. + 1. If the issue is **closed**, check whether the proposed fix resolves your issue. +1. Report it via our [**GitHub Issues**](https://github.com/Azure/Enterprise-Scale/issues) +1. Select `New issue` and use the `Feature request 🚀` template +1. Ensure you fill out the template with as much information as possible, being sure to cover off what's needed for maintainers and the community to: + 1. Understand your feature and how it aligns to our [conceptual architecture](https://docs.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/#azure-landing-zone-conceptual-architecture), [design principles](https://docs.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-principles) and [design areas](https://docs.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-areas) :memo: + 1. Optionally, let us know if you would like to contribute by adding your requested feature via a [**Pull Request**](https://github.com/Azure/Enterprise-Scale/pulls) :wrench: + +> **IMPORTANT:** If you are proposing a change to any of the Azure landing zone guidance, please include a business case explaining why you feel this will benefit our community. + +### Report a security vulnerability + +Please see our [**security policy**](https://github.com/Azure/Enterprise-Scale/security/policy) for more information. + +### Working with ALZ Custom policies + +Policies in the Azure Landing Zone reference implementations and repository are custom to Azure environments. They are definitions which are recommended when working with ALZ landing zones. The policies used in the reference implementations are mastered from the Enterprise-Scale repository. + +To work with policies, they are location in [src/resources/Microsoft.Authorization/*](https://github.com/Azure/Enterprise-Scale/blob/main/src/resources/Microsoft.Authorization). + +To create a new policy, it is worth taking the framework from an already existing policy. + +In ALZ Custom there is a way to name the custom policies that are used. They are prefixed with one of the following: `Append`, `Audit`, `Deny` or `Deploy` + +#### **Append** + +When contributing a custom policy based on appending resources at scale, the correct prefix would be `Append` - such as `Append-AppService-httpsonly.json`. + +#### **Audit** + +Auditing resources at scale via policy is achievable using the correct effect inside the definition. This policy contribution should be prefixed with `Audit` - in example, `Audit-MachineLearning-PrivateEndpointId.json`. + +#### **Deny** + +Deny policies are used to prevent the creation/action of and on Azure resources. Policies being created and contributed should be prefixed with 'Deny' - in example `Deny-Databricks-Sku.json`. + +#### **Deploy** + +Deploy follows the DeployIfNotExists (DINE) methodology. Policy contribution should be named prefixed with `Deploy` - in example `Deploy-Custom-Route-Table.json`. + +The naming convetion should be formatted in the following manner: `{prefix}-{resourceType}-{targetSetting}.json`. In an example: `Deny-SqlMi-minTLS.json`. + +When creating the naming convention for the definition, it must company with the [Naming rule and restrictions for Azure resources | Microsoft Authorization](https://learn.microsoft.com/azure/azure-resource-manager/management/resource-name-rules#microsoftauthorization) standard. + +Once the `Name` in the file name and `Name` in the policy definition have been set, it is worth noting that they should not be changed as it can impact initiatives and assignments. + +Inside of the JSON is a `metadata` section which is required for policy creation. + +![Policy Metadata](https://github.com/Azure/Enterprise-Scale/blob/main/docs/wiki/media/policy-metadata-example.png) + +| Metadata Value | Description | +|----------------------|------------------------------------------------------------| +| Version | Version of the policy definition | +| Category | The category which the policy definition will reside in | +| Source | The source repository for the policy definition | +| alzCloudEnvironments | The cloud environment for which the policy is designed for | + +The definition created then needs to be included in the [policies.bicep](https://github.com/Azure/Enterprise-Scale/blob/main/src/templates/policies.bicep) file inside of [src/templates/](https://github.com/Azure/Enterprise-Scale/blob/main/src/templates/) under the correct context. An additional line needs to be created under the respective variable in the file, depending on it being a policy definition or a policy set definition: + +![Policies bicep file example 1](https://github.com/Azure/Enterprise-Scale/blob/main/docs/wiki/media/policies-bicep-example.png) + +For a policy definition, additional code should be added inside of the `loadPolicyDefinitions` variable under the correct environment: + +`loadTextContent('../resources/Microsoft.Authorization/policyDefinitions/Name-Of-The-Policy.json')` + +For a policy set definition, additional code should be added inside of the `loadPolicySetDefinitions` variable under the correct environment: + +`loadTextContent('../resources/Microsoft.Authorization/policySetDefinitions/Deploy-Sql-Security.json')` + +The policy definition files will be compiled into a `policies.json` file from the `policy.bicep` file which was amended. + +Once the policy work has been completed, a pull request has been submitted to the repository: + +![pr-example](https://github.com/Azure/Enterprise-Scale/blob/main/docs/wiki/media/pr-example.png) + +Policy versioning follows the same protocol as built-in policies. More information on that can be found in the [ALZ Policies document in the wiki](https://github.com/Azure/Enterprise-Scale/blob/main/docs/wiki/ALZ-Policies.md#versioning). + +For policy deprecation, the process is documented in the [Azure Landing Zones - Deprecating Policies](https://github.com/Azure/Enterprise-Scale/blob/main/docs/wiki/ALZ-Deprecated-Services.md) page. + +If a policy is part of an initiative, references to policies that are being deprecated should be removed. Policy initiatives are located in the [policySetDefinitions](https://github.com/Azure/Enterprise-Scale/blob/main/src/resources/Microsoft.Authorization/policySetDefinitions/) folder. To find out if a policy is part of an initiative it is recommended to look up the policy definition in [AzAdvertiser](http://azadvertizer.com/) and check for association with initiatives. When identified, go into the necessary initiative and remove references to the definition. Locate the policy definition in the parameters of the initiative and remove reference: + +![Example policy def in initiative](https://github.com/Azure/Enterprise-Scale/blob/main/docs/wiki/media/example-def-in-init.png) + +Also find it in the policyDefinitions and remove reference as well: + +![Example policy def in initiative 2](https://github.com/Azure/Enterprise-Scale/blob/main/docs/wiki/media/example-def-in-init-2.png) + +When working within the policy files, to read parameters which are set at the top level of the policy definition a double escape is needed for ARM. So instead of using `[parameters('someParameter')]` within the policy, you should use `[[parameters('someParameter')]` instead. + +> **Note:** When testing the policy manually in the portal or another deployment outside of the ALZ Accelerator (Portal), you will need to remove the double escaping, `[[`, and revert to normal ,`[`' + +When working with policies that are assigned by default, these are located under the [eslzArm/managementGroupTemplates/policyAssignments](https://github.com/Azure/Enterprise-Scale/blob/main/eslzArm/managementGroupTemplates/policyAssignments) folder. References to policy definitions are done through the assignments, so if any amendments are done to default assigned policies, they should be amended here too. A wiki to default assignments can be found [in the wiki](https://github.com/Azure/Enterprise-Scale/blob/main/docs/wiki/ALZ-Policies.md). + +Policies in `eslzArm.json` file will also need updating if wanting to assign a new policy that is located. The file for this amendment [in eslzArm/eslzArm.json](https://github.com/Azure/Enterprise-Scale/blob/main/eslzArm/eslzArm.json). + +### Forking the repository and submitting a Pull Request + +To start contributing to this guide is it worth reviewing the developer workflow for contribution [which is documented in GitHub](https://docs.github.com/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork). + +## Code of Conduct + +We are working hard to build strong and productive collaboration with our passionate community. We heard you loud and clear. Follow the [Code of Conduct](https://github.com/Azure/Enterprise-Scale/blob/main/CODE_OF_CONDUCT.md). diff --git a/docs/wiki/ALZ-Deploy-landing-zones.md b/docs/wiki/ALZ-Deploy-landing-zones.md new file mode 100644 index 0000000000..9e5fcb5a95 --- /dev/null +++ b/docs/wiki/ALZ-Deploy-landing-zones.md @@ -0,0 +1,40 @@ +# Create Landing Zone(s) + +It is now time to turn the lights ON :bulb: + +At this point you have the necessary platform setup configured to support one or many Landing Zone(s) with the required definitions (Roles, Policies and PolicySet) and assignments (Roles and Policies). + +Provisioning Landing Zone(s) will mean either **creating a new subscription** or **moving an existing subscription** to the desired Management Group and the platform will do the rest. In large environments with 10s and 100s of Landing Zones, the platform team can also delegate Landing Zone(s) to the respective business units and/or application portfolio owners while being confident that security, compliance and monitoring requirements are being met. Furthermore, the platform team may also delegate the necessary access permissions such as: + +1) IAM roles to create new subscriptions +2) Place subscriptions in the appropriate Management Groups for business units and/or application portfolio owners to provide self-service access to create their own Landing Zone(s). + +## Create or move a Subscription under the Landing Zone Management Group + +Depending upon the reference implementation that's deployed, navigate to the appropriate Management Group under the "Landing Zones" Management Group and create or move an existing subscription. This can be done via the Azure Portal or PowerShell/CLI. + +Business units and/or application portfolio owners can use their preferred tool chain - ARM, PowerShell, Terraform, Portal, CLI etc. for subsequent resource deployments within their respective Landing Zone(s). + +### Create new subscriptions into the **Landing zones** > **Corp** or **Online** Management Group + +1. In the Azure portal, navigate to Subscriptions +2. Click 'Add', and complete the required steps in order to create a new subscription. +3. When the subscription has been created, go to Management Groups and move the subscription into the **Landing zones** > **Corp** or **Online** Management Group +4. Assign RBAC permissions for the application team/user(s) who will be deploying resources in to the newly created subscription + +### Move existing subscriptions into the **Landing zones** > **Corp** or **Online** Management Group + +1. In the Azure portal, navigate to Management Groups +2. Locate the subscription you want to move, and move it in to the **Landing zones** > **Corp** or **Online** Management Group +3. Assign RBAC permissions for the application team/user(s) who will be deploying resources in to the subscription + +## Create Enterprise-Scale Landing Zones using the Azure Portal + +The following deployment experiences can be leveraged to create multiple landing zones (subscriptions) and target individual Management Groups (e.g., 'online', 'corp' etc.). + +To use the ARM templates below to create new subscriptions, you must have Management Group Contributor or Owner permissions on the Management Group where you will invoke the deployment and also on the targeted Management Groups for the new subscriptions, as well as subscription write permissions on the billing account. + +| Agreement types | ARM Template | Description +|:-------------------------|:-------------|:--------------| +| Enterprise Agreement (EA) |[![Deploy To Azure](https://docs.microsoft.com/azure/templates/media/deploy-to-azure.svg)](https://portal.azure.com/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2Fdocs%2Freference%2Flzs%2FarmTemplates%2Feslz.json/createUIDefinitionUri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2Fdocs%2Freference%2Flzs%2FarmTemplates%2Fportal-eslz.json) | Create 'N' number of subscriptions into multiple Management Groups +| Enterprise Agreement (EA) |[![Deploy To Azure](https://docs.microsoft.com/azure/templates/media/deploy-to-azure.svg)](https://portal.azure.com/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2Fexamples%2Flanding-zones%2Fsubscription-with-rbac%2FsubscriptionWithRbac.json/createUIDefinitionUri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2Fexamples%2Flanding-zones%2Fsubscription-with-rbac%2Fportal-subscriptionWithRbac.json)| Create a subscription with RBAC for SPN diff --git a/docs/wiki/ALZ-Deploy-reference-implementations.md b/docs/wiki/ALZ-Deploy-reference-implementations.md new file mode 100644 index 0000000000..b067fcf884 --- /dev/null +++ b/docs/wiki/ALZ-Deploy-reference-implementations.md @@ -0,0 +1,30 @@ +# Deploy Enterprise-Scale Reference implementation in your own environment + +This section will guide you through the process of deploying an Enterprise-Scale reference implementation in your own environment. + +## What is an Enterprise-Scale Reference Implementation? + +The Enterprise-Scale design principles and reference implementations can be adopted by all customers no matter what the size or history of their Azure estate. The following reference implementations target the most common customer scenarios for adopting Enterprise-Scale. + +## Deploy a Reference Implementation + +| Reference implementation | Description | ARM Template | Link | +|:-------------------------|:-------------|:-------------|------| +| Contoso | On-premises connectivity using Azure vWAN |[![Deploy To Azure](https://docs.microsoft.com/azure/templates/media/deploy-to-azure.svg)](https://portal.azure.com/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2FeslzArm%2FeslzArm.json/uiFormDefinitionUri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2FeslzArm%2Feslz-portal.json) | [Detailed description](https://github.com/Azure/Enterprise-Scale/blob/main/docs/reference/contoso/Readme.md) | +| AdventureWorks | On-premises connectivity with Hub & Spoke |[![Deploy To Azure](https://docs.microsoft.com/azure/templates/media/deploy-to-azure.svg)](https://portal.azure.com/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2FeslzArm%2FeslzArm.json/uiFormDefinitionUri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2FeslzArm%2Feslz-portal.json) | [Detailed description](https://github.com/Azure/Enterprise-Scale/blob/main/docs/reference/adventureworks/README.md) | +| WingTip | Azure without hybrid connectivity |[![Deploy To Azure](https://docs.microsoft.com/azure/templates/media/deploy-to-azure.svg)](https://portal.azure.com/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2FeslzArm%2FeslzArm.json/uiFormDefinitionUri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2FeslzArm%2Feslz-portal.json) | [Detailed description](https://github.com/Azure/Enterprise-Scale/blob/main/docs/reference/wingtip/README.md) | +| Trey Research | For small enterprises | [![Deploy To Azure](https://docs.microsoft.com/azure/templates/media/deploy-to-azure.svg)](https://portal.azure.com/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2Fdocs%2Freference%2Ftreyresearch%2FarmTemplates%2Fes-lite.json/createUIDefinitionUri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2Fdocs%2Freference%2Ftreyresearch%2FarmTemplates%2Fportal-es-lite.json) | [Detailed description](https://github.com/Azure/Enterprise-Scale/blob/main/docs/reference/treyresearch/README.md) | + +> The Bicep version is now available in Public Preview here: [https://github.com/Azure/ALZ-Bicep](https://github.com/Azure/ALZ-Bicep) + +An Enterprise-Scale reference implementation is rooted in the principle that **Everything in Azure is a Resource**. All of the reference scenarios leverage native **Azure Resource Manager (ARM)** to describe and manage their resources as part of their target state architecture at-scale. + +Reference implementations enable security, monitoring, networking, and any other plumbing needed for landing zones (i.e. Subscriptions) autonomously through policy enforcement. Companies will deploy the Azure environment with ARM templates to create the necessary structure for management and networking to declare a desired goal state. All scenarios will apply the principle of "Policy Driven Governance" for landing zones by using Azure Policy. The benefits of a policy-driven approach are many but the most significant are: + +1. Platform can provide an orchestration capability to bring target resources (in this case a subscription) to a desired goal state. + +2. Continuous conformance to ensure all platform-level resources are compliant. Because the platform is aware of the goal state, the platform can assist with the monitoring and remediation of resources throughout their life-cycle. + +3. Platform enables autonomy regardless of the customer's scale point. + +To know and learn more about ARM templates used for above reference implementation, please follow [this](https://github.com/Azure/Enterprise-Scale/blob/main/docs/Deploy/es-schema.md) article. diff --git a/docs/wiki/ALZ-Deploy-workloads.md b/docs/wiki/ALZ-Deploy-workloads.md new file mode 100644 index 0000000000..715654b528 --- /dev/null +++ b/docs/wiki/ALZ-Deploy-workloads.md @@ -0,0 +1,44 @@ +# Deploy workloads into the landing zones + +At this point you have the necessary platform setup and landing zones (subscriptions) created and placed into their respective management groups, being secure, governed, monitored, and enabled for autonomy and are ready for your application teams to do workload deployments, migrations, and net-new development to their landing zones. + +The following workloads outlined here provides best-practices, and curated deployment experiences for your application teams to successfully deploy them into their landing zones (online, corp). + +## AKS (Kubernetes) + +Deploy Kubernetes to Azure and integrate with ARM, Azure AD, Azure Policy, and Azure Monitor to ensure you have a production ready Kubernetes cluster in your landing zone +a +| Landing zone | ARM Template | Details | +|:-------------------------|:-------------|:-----------| +| Online |[![Deploy To Azure](https://docs.microsoft.com/azure/templates/media/deploy-to-azure.svg)](https://portal.azure.com/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2Fworkloads%2FAKS%2FarmTemplates%2Fonline-aks.json/createUIDefinitionUri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FEnterprise-Scale%2Fmain%2Fworkloads%2FAKS%2FarmTemplates%2Fportal-online-aks.json) | [Detailed description](https://github.com/Azure/Enterprise-Scale/tree/main/workloads/AKS/README.md) +| Corp | Coming soon | Detailed description + + +### SAP (coming soon) + +Details coming soon + +| Landing zone | ARM Template | Details | +|:-------------------------|:-------------|:-----------| +| Online | Coming soon +| Corp | Coming soon + + +### Windows Virtual Desktop (coming soon) + +Details coming soon + +| Landing zone | ARM Template | Details | +|:-------------------------|:-------------|:-----------| +| Online | Coming soon +| Corp | Coming soon + + +### Data and Analytics (coming soon) + +Details coming soon + +| Landing zone | ARM Template | Details +|:-------------------------|:-------------|:-----------| +| Online | Coming soon +| Corp | Coming soon \ No newline at end of file diff --git a/docs/wiki/ALZ-Deprecated-Services.md b/docs/wiki/ALZ-Deprecated-Services.md index aa90f9cd7f..0dd8cf28b1 100644 --- a/docs/wiki/ALZ-Deprecated-Services.md +++ b/docs/wiki/ALZ-Deprecated-Services.md @@ -1,11 +1,8 @@ -# Azure Landing Zones Deprecated Policies +# Azure Landing Zones Deprecated Services ## In this section -- [Azure Landing Zones Deprecated Policies](#azure-landing-zones-deprecated-policies) - - [In this section](#in-this-section) - - [Overview](#overview) - - [Deprecated policies](#deprecated-policies) +- [Azure Landing Zones Deprecated Services](#azure-landing-zones-deprecated-services) ## Overview @@ -24,3 +21,7 @@ Over time, a deprecation process of there `ALZ / custom` policies will have to t | Deploy-Nsg-FlowLogs | [e920df7f-9a64-4066-9b58-52684c02a091](https://www.azadvertizer.net/azpolicyadvertizer/e920df7f-9a64-4066-9b58-52684c02a091.html?) | Custom policy replaced by built-in requires less administration overhead | | Deploy-Nsg-FlowLogs-to-LA | [e920df7f-9a64-4066-9b58-52684c02a091](https://www.azadvertizer.net/azpolicyadvertizer/e920df7f-9a64-4066-9b58-52684c02a091.html?) | Custom policy replaced by built-in requires less administration overhead | | Deny-PublicIP | [6c112d4e-5bc7-47ae-a041-ea2d9dccd749](https://www.azadvertizer.net/azpolicyadvertizer/6c112d4e-5bc7-47ae-a041-ea2d9dccd749.html?) | Custom policy replaced by built-in requires less administration overhead |½ + +## Deprecated services + +- Removed `ActivityLog` Solution as an option to be deployed into the Log Analytics Workspace. As this has been superseded by the Activity Log Insights Workbook, as documented [here.](https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log-insights) \ No newline at end of file diff --git a/docs/wiki/ALZ-Known-Issues.md b/docs/wiki/ALZ-Known-Issues.md new file mode 100644 index 0000000000..029dcb61cc --- /dev/null +++ b/docs/wiki/ALZ-Known-Issues.md @@ -0,0 +1,26 @@ +# Reference Implementation - Known Issues + +The list below summarizes the known issues currently being worked on by the Enterprise-Scale team. + +These have been discovered whilst running the reference implementation, and customers may come across them when implementing Enterprise-Scale to build and operationalize their Azure platform. + +Some of these issues may be resolved in future release, while others require input from specific Azure product teams. + +## Deploying the reference implementation fails due to 'Policy cannot be found (404)' + +### Area +ARM backend storage + +### Issue +When deploying to a region that is paired (e.g., EastUS, which is paired with WestUS), resources deployed in deployment 1 who's referenced in deployment 2 may fail due to replication latency in ARM backend storage. This will cause the overall deployment to fail + +### Status +While this is being fixed, it is recommended to re-run the deployment of the reference implementation with the same input parameter, and the deployment should succeed. + +## Unsupported number of Tenants in context: x TenantID(s) + +### Issue +We currently do not support Initialization across multiple Tenants.
Clear your AzContext and run `Connect-AzAccount` with the service principal that was created earlier. + +### Status +No fix as of yet. diff --git a/docs/wiki/ALZ-Policies.md b/docs/wiki/ALZ-Policies.md index fc28499774..428357f81b 100644 --- a/docs/wiki/ALZ-Policies.md +++ b/docs/wiki/ALZ-Policies.md @@ -64,7 +64,7 @@ The table below provides the specific **Custom** and **Built-in** **policy defin | Assignment Name | Definition Name | Policy Type | Description | Effect(s) | Version | | -------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------- | ------- | | **Deploy Microsoft Defender for Cloud configuration** | **Deploy Microsoft Defender for Cloud configuration** | `Policy Definition Set`, **Custom** | Configures all the MDFC settings, such as Microsoft Defender for Cloud per individual service, security contacts, and export from MDFC to Log Analytics workspace | DeployIfNotExists | 3.0.0 | -| **Deploy-Resource-Diag** | **Deploy Diagnostic Settings to Azure Services** | `Policy Definition Set`, **Custom** | This policy set deploys the configurations of application Azure resources to forward diagnostic logs and metrics to an Azure Log Analytics workspace. | DeployIfNotExists | 1.0.0 | +| **Deploy-Resource-Diag** | **Deploy Diagnostic Settings to Azure Services** | `Policy Definition Set`, **Custom** | This policy set deploys the configurations of application Azure resources to forward diagnostic logs and metrics to an Azure Log Analytics workspace. | DeployIfNotExists | 2.0.0 | | **Enable Monitoring in Azure Security Center** | **Azure Security Benchmark** | `Policy Definition Set`, **Built-in** | The Microsoft Cloud Security Benchmark initiative represents the policies and controls implementing security recommendations defined in Microsoft Cloud Security Benchmark v1, see https://aka.ms/azsecbm. This also serves as the Azure Security Center default policy initiative. You can directly assign this initiative, or manage its policies and compliance results within Azure Security Center. | Audit, AuditIfNotExists, Disabled | 49.0.0 | | **Enable Azure Monitor for VMs** | **Enable Azure Monitor for VMs** | `Policy Definition Set`, **Built-in** | Enable Azure Monitor for the virtual machines (VMs) in the specified scope (management group, subscription or resource group). Takes Log Analytics workspace as parameter | DeployIfNotExists, AuditIfNotExists | 2.0.0 | | **Enable Azure Monitor for Virtual Machine Scale Sets** | **Enable Azure Monitor for Virtual Machine Scale Sets** | `Policy Definition Set`, **Built-in** | Enable Azure Monitor for the Virtual Machine Scale Sets in the specified scope (Management group, Subscription or resource group). Takes Log Analytics workspace as parameter. Note: if your scale set upgradePolicy is set to Manual, you need to apply the extension to the all VMs in the set by calling upgrade on them. In CLI this would be az vmss update-instances. | DeployIfNotExists, AuditIfNotExists | 1.0.1 | @@ -289,3 +289,65 @@ This management group is for subscriptions that will only be used for testing an | `Policy Definition Sets` | **0** | | `Policy Definitions` | **0** | + +### Versioning + +Each policy definition and initiative contains a version in its metadata section: +```json +"metadata": { + "version": "1.0.0", + "category": "{categoryName}", + "source": "https://github.com/Azure/Enterprise-Scale/", + "alzCloudEnvironments": [ + "AzureCloud", + "AzureChinaCloud", + "AzureUSGovernment" + ] +} +``` + +This version is incremented according to the following rules (subject to change): + - **Major Version** (**1**.0.0) + - Policy Definitions + - Rule logic changes + - ifNotExists existence condition changes + - Major changes to the effect of the policy (i.e. adding a new resource to a deployment) + - Policy Set Definitions + - Addition or removal of a policy definition from the policy set + - **Minor Version** (1.**0**.0) + - Policy Definitions + - Changes to effect details that don't meet the major version criteria + - Adding new parameter allowed values + - Adding new parameters (with default values) + - Other minor changes to existing parameters + - Policy Set Definitions + - Adding new parameter allowed values + - Adding new parameters (with default values) + - Other minor changes to existing parameters + - **Patch Version** (1.0.**0**) + - Policy Definitions + - String changes (displayName, description, etc…) + - Other metadata changes + - Policy Set Definitions + - String changes (displayName, description, etc…) + - Other metadata changes + - **Suffix** + - Append "-preview" to the version if the policy is in a preview state + - Example: 1.3.2-preview + - Append "-deprecated" to the version if the policy is in a deprecated state + - Example: 1.3.2-deprecated + +## Preview and deprecated policies + +This section aims to explain what it means when a built-in policy has a state of ‘preview’ or ‘deprecated’. + +Policies can be in preview because a property (alias) referenced in the policy definition is in preview, or the policy is newly introduced and would like additional customer feedback. A policy may get deprecated when the property (alias) becomes deprecated & not supported in the resource type's latest API version, or when there is manual migration needed by customers due to a breaking change in a resource type's latest API version. + +When a policy gets deprecated or gets out of preview, there is no impact on existing assignments. Existing assignments continue to work as-is. The policy is still evaluated & enforced like normal and continues to produce compliance results. + +Here are the changes that occur when a policy gets deprecated: +- Display name is appended with ‘[Deprecated]:’ prefix, so that customers have awareness to migrate or delete the policy. +- Description gets updated to provide additional information regarding the deprecation. +- The version number is updated with ‘-deprecated’ suffix. (see [Policy Versioning](#versioning) above) + +> **NOTE:** The `name` value must not change in the file through deprecation or preview. diff --git a/docs/wiki/ALZ-Setup-aad-permissions.md b/docs/wiki/ALZ-Setup-aad-permissions.md new file mode 100644 index 0000000000..9a1aeec70a --- /dev/null +++ b/docs/wiki/ALZ-Setup-aad-permissions.md @@ -0,0 +1,67 @@ +# Configure Azure Active Directory permissions for Service Principal + +This article will guide you through the process to add your AzOps service principal to the Azure Active Directory [Directory Readers](https://docs.microsoft.com/azure/active-directory/users-groups-roles/directory-assign-admin-roles) role. + +> Note: The steps below requires you to use an identity that is local to the Azure AD, and **_not_** Guest user account due to known restrictions. + +The service principal used by the Enterprise-Scale reference implementation requires Azure AD directory reader permissions to be able to discover Azure role assignments. These permissions are used to enrich data around the role assignments with additional Azure AD context such as ObjectType and Azure AD Object DisplayName. + +## Add service principal to directory role via Azure Portal (Option 1) + +1.1 Sign in to the Azure portal or the Azure Active Directory admin center as a Global Administrator. If you are using Azure AD Privileged Identity Management, activate your Global Administrator role assignment. + +1.2 Open Azure Active Directory. + +1.3 Under _Manage_ > _Roles and administrators_, select _Directory readers_. +![alt](./media/aad-rolesandadministrators.png) + +1.4 Under _Manage_ > _Assignments_ > _Add assignments_, find for and select your AzOps service principal and finally add it to the directory role. + +![alt](./media/directory-reader.png) + +> Note: In case you are using Azure AD Privileged Identity management, ensure you add the service principal to the role with a permanent assignment. + +## Add service principal to directory role with Azure AD PowerShell (Option 2) + +Ensure that you have the [AzureAD PowerShell module installed on your machine](https://docs.microsoft.com/powershell/module/azuread/?view=azureadps-2.0) and that you have connected to Azure AD with the [Connect-AzureAD](https://docs.microsoft.com/powershell/module/azuread/connect-azuread?view=azureadps-2.0) cmdlet. + + +````powershell +#Param -- Default is AZOps +$ADServicePrincipal = "AZOps" + +#verify if AzureAD module is installed and running a minimum version, if not install with the latest version. +if ((Get-InstalledModule -Name "AzureAD" -MinimumVersion 2.0.2.130 ` -ErrorAction SilentlyContinue) -eq $null) { + + Write-Host "AzureAD Module does not exist" -ForegroundColor Yellow + Install-Module -Name AzureAD -Force + Import-Module -Name AzureAD + Connect-AzureAD #sign in to Azure from Powershell, this will redirect you to a webbrowser for authentication, if required + +} +else { + Write-Host "AzureAD Module exists with minimum version" -ForegroundColor Yellow + Import-Module -Name AzureAD + Connect-AzureAD #sign in to Azure from Powershell, this will redirect you to a webbrowser for authentication, if required +} + +#Verify Service Principal and if not pick a new one. +if (!(Get-AzureADServicePrincipal -Filter "DisplayName eq '$ADServicePrincipal'")) { + Write-Host "ServicePrincipal doesn't exist or is not AZOps" -ForegroundColor Red + break +} +else { + Write-Host "$ADServicePrincipal exist" -ForegroundColor Green + $ServicePrincipal = Get-AzureADServicePrincipal -Filter "DisplayName eq '$ADServicePrincipal'" + #Get Azure AD Directory Role + $DirectoryRole = Get-AzureADDirectoryRole -Filter "DisplayName eq 'Directory Readers'" + #Add service principal to Directory Role + Add-AzureADDirectoryRoleMember -ObjectId $DirectoryRole.ObjectId -RefObjectId $ServicePrincipal.ObjectId +} +```` + +Please note, it may take up to 15-30 minutes for permission to propagate in Azure AD. + +## Next steps + +Please proceed with [deploying reference implementation](./ALZ-Deploy-reference-implementations). diff --git a/docs/wiki/ALZ-Setup-azure.md b/docs/wiki/ALZ-Setup-azure.md new file mode 100644 index 0000000000..e60e14b696 --- /dev/null +++ b/docs/wiki/ALZ-Setup-azure.md @@ -0,0 +1,74 @@ +# Configure Azure permissions for ARM tenant deployments + +This article will guide you through the process of configuring permissions in your Azure environment to enable ARM tenant level deployments. + +> Note: The steps below require you to use an identity that is local to the Azure AD, and **_not_** Guest user account due to known restrictions. + +Enterprise-Scale reference implementation requires permission at tenant root scope "/" to be able to configure Management Group and create/move subscription. In order to grant permission at tenant root scope "/", users in "AAD Global Administrators" group can temporarily elevate access, to manage all Azure resources in the directory. + +Once the User Access Administrator (UAA) role is enabled, a UAA can grant **_other users and service principals_** within organization to deploy/manage Enterprise-Scale reference implementation by granting "Owner" permission at tenant root scope "/". + +Once permission is granted to other **users and service principals**, you can safely disable "User Access Administrator" permission for the "AAD Global Administrator" users. For more information please follow this article [elevated account permissions](https://docs.microsoft.com/azure/role-based-access-control/elevate-access-global-admin) + +## 1. Elevate Access to manage Azure resources in the directory + +1.1 Sign in to the Azure portal or the Azure Active Directory admin center as a Global Administrator. If you are using Azure AD Privileged Identity Management, activate your Global Administrator role assignment. + +1.2 Open Azure Active Directory. + +1.3 Under _Manage_, select _Properties_. +![alt](https://docs.microsoft.com/azure/role-based-access-control/media/elevate-access-global-admin/azure-active-directory-properties.png) + +1.4 Under _Access management for Azure resources_, set the toggle to Yes. + +![alt](https://docs.microsoft.com/azure/role-based-access-control/media/elevate-access-global-admin/aad-properties-global-admin-setting.png) + +## 2. Grant Access to User and/or Service principal at root scope "/" to deploy Enterprise-Scale reference implementation + +Please ensure you are logged in as a user with UAA role enabled in AAD tenant and logged in user is not a guest user. + +Bash + +````bash +#sign into AZ CLI, this will redirect you to a webbrowser for authentication, if required +az login + +#if you do not want to use a web browser you can use the following bash +read -sp "Azure password: " AZ_PASS && echo && az login -u -p $AZ_PASS + +#assign Owner role at Tenant root scope ("/") as a User Access Administrator to current user (gets object Id of the current user (az login)) +az role assignment create --scope '/' --role 'Owner' --assignee-object-id $(az ad signed-in-user show --query id --output tsv) --assignee-principal-type User + +#(optional) assign Owner role at Tenant root scope ("/") as a User Access Administrator to service principal (set spn_displayname to your service principal displayname) +spn_displayname='' +az role assignment create --scope '/' --role 'Owner' --assignee-object-id $(az ad sp list --display-name $spn_displayname --query '[].{objectId:objectId}' -o tsv) --assignee-principal-type ServicePrincipal +```` + +PowerShell + +````powershell +#sign in to Azure from Powershell, this will redirect you to a webbrowser for authentication, if required +Connect-AzAccount + +#get object Id of the current user (that is used above) +$user = Get-AzADUser -UserPrincipalName (Get-AzContext).Account + +#assign Owner role at Tenant root scope ("/") as a User Access Administrator to current user +New-AzRoleAssignment -Scope '/' -RoleDefinitionName 'Owner' -ObjectId $user.Id + +#(optional) assign Owner role at Tenant root scope ("/") as a User Access Administrator to service principal (set $spndisplayname to your service principal displayname) +$spndisplayname = "" +$spn = (Get-AzADServicePrincipal -DisplayName $spndisplayname).id +New-AzRoleAssignment -Scope '/' -RoleDefinitionName 'Owner' -ObjectId $spn +```` + +Please note, it may take up to 15-30 minutes for permission to propagate at tenant root scope. It is highly recommended that you log out and log back in. + +### Creating a scoped role assignment + +The Owner privileged root tenant scope *is required* in the deployment of the [Reference implementation](./ALZ-Deploy-reference-implementations). However post deployment, and as your use of Enterprise Scale matures, you are able to limit the scope of the Service principal roleAssignments to a subsection of the Management Group hierarchy. +Eg. `"/providers/Microsoft.Management/managementGroups/YourMgGroup"`. + +## Next steps + +Please proceed with [deploying reference implementation](./ALZ-Deploy-reference-implementations). diff --git a/docs/wiki/Create-Landingzones.md b/docs/wiki/Create-Landingzones.md index 5c802875af..67cbd79210 100644 --- a/docs/wiki/Create-Landingzones.md +++ b/docs/wiki/Create-Landingzones.md @@ -23,7 +23,7 @@ One of the benefits using this approach is the management of platform security a ## Pre-requisites -Before getting started with this first steps ensure that AzOps has been [setup and configured for the target environment](Deploying-Enterprise-Scale.md#validation-post-deployment-github). In this documentation the same Service Principal will be used to to assign the permission to create landing zones (subscription). +Before getting started with this first steps ensure that AzOps has been [setup and configured for the target environment](./Deploying-Enterprise-Scale#validation-post-deployment-github). In this documentation the same Service Principal will be used to to assign the permission to create landing zones (subscription). For the Service Principal permissions to create subscriptions, access to an *enrollment account* that has a billing id associated is required. @@ -35,7 +35,7 @@ Creating Azure subscriptions programmatically is allowed on specific types of Az This section describes how AzOps is used to create subscriptions (landing zones) under management groups using ARM templates. In the following steps the *Enrollment account subscription creator* role will be assigned to a SPN as illustrated in the following article: -![EA account / Service Principal](media/ea-account-spn.png) +![EA account / Service Principal](./media/ea-account-spn.png) **Login and fetch access token** Login with the *enrollment account* (e.g. with `Login-AzAccount`) and execute the following commands to fetch a valid access token for the account: @@ -140,11 +140,11 @@ PlatformOps will use AzOps CI/CD pipelines to create subscriptions (landing zone ## Create a new landing zone (subscriptions) -Creating a landing zone (subscription) is as simple as creating any other resource in Azure. The same sequence of steps will be needed as used for other platform resource deployments (e.g. [deploy a policyAssignments](./Deploying-Enterprise-Scale.md#create-new-policy-assignment-for-validation)). +Creating a landing zone (subscription) is as simple as creating any other resource in Azure. The same sequence of steps will be needed as used for other platform resource deployments (e.g. [deploy a policyAssignments](./Deploying-Enterprise-Scale#create-new-policy-assignment-for-validation)). To successfully deploy a subscription using AzOps the following steps will be required: -- 'Connect' AzOps to the Azure Environment, ensure that ['Pull' workflow runs successfully](./Deploying-Enterprise-Scale.md#validation-post-deployment-github) +- 'Connect' AzOps to the Azure Environment, ensure that ['Pull' workflow runs successfully](./Deploying-Enterprise-Scale#validation-post-deployment-github) - Enable the AzOps SPN for subscription creation as documented [here](#enable-service-principal-to-create-landing-zones) - Ensure that SPN has Owner permissions at the target management group the subscription will be deployed under diff --git a/docs/wiki/Deploying-ALZ-BasicSetup.md b/docs/wiki/Deploying-ALZ-BasicSetup.md index 512232ffc9..c5232ddf7b 100644 --- a/docs/wiki/Deploying-ALZ-BasicSetup.md +++ b/docs/wiki/Deploying-ALZ-BasicSetup.md @@ -89,7 +89,6 @@ See [Manage usage and costs with Azure Monitor Logs](https://docs.microsoft.com/ - [Agent Health](https://docs.microsoft.com/en-us/azure/azure-monitor/insights/solution-agenthealth) helps you understand which monitoring agents are unresponsive and submitting operational data. - [Change Tracking](https://docs.microsoft.com/en-us/azure/automation/change-tracking/overview) tracks changes in virtual machines hosted in Azure, on-premises, and other cloud environments to help you pinpoint operational and environmental issues. - [Update Management](https://docs.microsoft.com/en-us/azure/automation/update-management/overview) assesses the status of available updates and allows you manage the process of installing required updates for your machines leveraging Azure Automation. - - [Activity Log](https://docs.microsoft.com/en-us/azure/azure-monitor/essentials/activity-log#activity-log-analytics-monitoring-solution) helps to assess administration and operational events related to your subscriptions. - [VM Insights](https://docs.microsoft.com/en-us/azure/azure-monitor/vm/vminsights-overview) monitors the performance and health of your virtual machines and virtual machine scale sets, including their running processes and dependencies on other resources. - [Service Map](https://docs.microsoft.com/en-us/azure/azure-monitor/vm/service-map) automatically discovers application components on Windows and Linux systems and maps the communication between services. - [SQL Assessment](https://docs.microsoft.com/en-us/azure/azure-monitor/insights/sql-assessment) provides a prioritized list of recommendations specific to your deployed server infrastructure. The recommendations are categorized across six focus areas which help you quickly understand the risk and take corrective action. diff --git a/docs/wiki/Deploying-Enterprise-Scale-BasicSetup.md b/docs/wiki/Deploying-Enterprise-Scale-BasicSetup.md index a60f10068b..55ea9c58c5 100644 --- a/docs/wiki/Deploying-Enterprise-Scale-BasicSetup.md +++ b/docs/wiki/Deploying-Enterprise-Scale-BasicSetup.md @@ -1,4 +1,3 @@ -## This page has moved +# This page has moved Please refer to [Azure landing zone portal accelerator deployment for Small Enterprises](./Deploying-ALZ-BasicSetup) - diff --git a/docs/wiki/Deploying-Enterprise-Scale-CustomerUsage.md b/docs/wiki/Deploying-Enterprise-Scale-CustomerUsage.md index fcf384289b..79a41b2509 100644 --- a/docs/wiki/Deploying-Enterprise-Scale-CustomerUsage.md +++ b/docs/wiki/Deploying-Enterprise-Scale-CustomerUsage.md @@ -1,30 +1,3 @@ -## Telemetry Tracking Using Customer Usage Attribution (PID) +# This page has moved -Microsoft can identify the deployments of the Azure Resource Manager templates with the deployed Azure resources. Microsoft can correlate these resources used to support the deployments. Microsoft collects this information to provide the best experiences with their products and to operate their business. The telemetry is collected through [customer usage attribution](https://docs.microsoft.com/azure/marketplace/azure-partner-customer-usage-attribution). The data is collected and governed by Microsoft's privacy policies, located at the [trust center](https://www.microsoft.com/trustcenter). - -To enable or disable the telemetry via the portal experience (recommended), use the radio toggle to specify your preference. - -Customer Usage Attribution Disabled: -![ESLZ ARM Template Telemetry Opt Out Toggle Control Disabled](./media/cua-portal-experience-disabled.jpg) -Customer Usage Attribution Enabled: -![ESLZ ARM Template Telemetry Opt Out Toggle Control Enabled](./media/cua-portal-experience-enabled.jpg) - - -Alternatively, to enable or disable this tracking via the ARM template experience, we have included a parameter called `telemetryOptOut` in order to opt out of telemetry tracking to the ESLZ ARM Template in this repo with a simple boolean flag. The default value `false` which **enables** the telemetry. If you would like to disable this tracking, then simply set this value to `true` and this module will not be included in deployments and **therefore disables** the telemetry tracking. - -In the `eslzARM.json` file, you will see the following: - -![ESLZ ARM Template parameter example](./media/cua-parameter.png) -![ESLZ ARM Template variable example](./media/cua-variable.png) -![ESLZ ARM Template resource example](./media/cua-resource.png) - - - -If you are happy with leaving telemetry tracking enabled, no changes are required. Please do not edit the module name or value of the variable `cuaID` in any module. - -## Module PID Value Mapping -The following are the unique ID's (also known as PIDs) used in each of the modules. - -| Module Name | PID | -| --------------------------- | ------------------------------------ | -| ALZ Accelerator/ESLZ ARM Deployment | 35c42e79-00b3-42eb-a9ac-e542953efb3c | +Please refer to [Telemetry Tracking Using Customer Usage Attribution (PID)](./Deploying-ALZ-CustomerUsage) diff --git a/docs/wiki/Deploying-Enterprise-Scale-Foundation.md b/docs/wiki/Deploying-Enterprise-Scale-Foundation.md index ee526ad8a7..7ae5d768d7 100644 --- a/docs/wiki/Deploying-Enterprise-Scale-Foundation.md +++ b/docs/wiki/Deploying-Enterprise-Scale-Foundation.md @@ -1,3 +1,3 @@ -## This page has moved +# This page has moved Please refer to [Azure landing zone portal accelerator deployment without hybrid connectivity](./Deploying-ALZ-Foundation) diff --git a/docs/wiki/Deploying-Enterprise-Scale-HubAndSpoke.md b/docs/wiki/Deploying-Enterprise-Scale-HubAndSpoke.md index 11cfcbf1bf..3c446d28dc 100644 --- a/docs/wiki/Deploying-Enterprise-Scale-HubAndSpoke.md +++ b/docs/wiki/Deploying-Enterprise-Scale-HubAndSpoke.md @@ -1,3 +1,3 @@ -## This page has moved +# This page has moved Please refer to [Deploy Azure landing zone portal accelerator deployment with hub and spoke network topology](./Deploying-ALZ-HubAndSpoke) diff --git a/docs/wiki/Deploying-Enterprise-Scale-Platform-DevOps.md b/docs/wiki/Deploying-Enterprise-Scale-Platform-DevOps.md index 688afb4690..2b223d19f0 100644 --- a/docs/wiki/Deploying-Enterprise-Scale-Platform-DevOps.md +++ b/docs/wiki/Deploying-Enterprise-Scale-Platform-DevOps.md @@ -1,288 +1,3 @@ -## Enterprise-Scale Platform DevOps and Automation +# This page has moved -### In this section: - -- [Enable deployment of Landing Zones with Infrastructure as Code using Github and Github Actions](#reference-implementation-deployment) -- [Validation post deployment (GitHub)](#validation-post-deployment-github) -- [Operating the Azure platform using AzOps (Infrastructure as Code with GitHub Actions)](#operating-the-azure-platform-using-azops-infrastructure-as-code-with-github-actions) - ---- - -### Enable deployment of Landing Zones with Infrastructure as Code using Github and Github Actions - -You can choose to bootstrap your CI/CD pipeline (GitHub with GitHub actions). Provide your GitHub user/org name, the preferred name of the GitHub repository that is to be created, as well as the PA token that the deployment will use to create a new repository and discover the Enterprise-Scale deployment ARM templates and merge them into your main branch. - -![Graphical user interface, text, application Description automatically generated](./media/clip_image015.png) - -1.1.1 To create a PA token, follow the instructions here: https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token - -1.1.2 Ensure the PA token has the following permissions: - -![Graphical user interface, text, application Description automatically generated](./media/github_developer_createPAT.png) - -> For Microsoft employees who are enrolled into the Azure GitHub organization, you must also authorize the PA token to this Org! - -![Graphical user interface, text, application, email Description automatically generated](./media/github_developer_enablesso.png) - -![Graphical user interface, text, application, email Description automatically generated](./media/github_developer_disablesso.png) - -1.2 Lastly, a Service Principal is required for Git to authenticate to – and be authorized to your Azure tenant. You can either use an existing Service Principal or create a new one. The Service Principal will be granted *Owner* permission on the top level Management Group that gets created. - -1.2.1 If using an existing Service Principal, ensure you have the *client secret* as this must be provided as the *Password* for the service principal and confirm it has the right level of permission. - -![Graphical user interface, text, application Description automatically generated](./media/clip_image020.jpg) - -1.2.2 If creating a new Service Principal, select "Create New" and click on Make selection” and the portal will open a new blade for app registration - -![img](./media/clip_image022.png) - - ![img](./media/clip_image024.png) - -Once the App has been registered, you must explicitly create a new secret. - - ![img](./media/clip_image026.png) - - ![img](./media/clip_image028.jpg) - -Make sure to note down the “Value” of the new client secret. - ![img](./media/clip_image030.jpg) - -The default API Permissions for this App are “User.Read”, as depicted below: - -![img](./media/clip_image032.jpg) - - After copying the secret, go to “Azure landing zone accelerator” (in the upper left) to return to the deployment. - - ![img](./media/clip_image034.png) - - At this point, paste the client secret value of the newly created client secret from a few step above into the Password field. - - ![Graphical user interface, application Description automatically generated](./media/clip_image035.png) - -### Validation post deployment (GitHub) - -Once Enterprise-Scale has deployed and you enabled the CI/CD bootstrap, you should validate in your GitHub account that: - -* A new repository has been created, with the name provided during setup. - -![Graphical user interface, text, application Description automatically generated](./media/clip_image040.png) - -* 4 Secrets are created into this GitHub repository. - -ARM_CLIENT_ID = Service Principal - -ARM_CLIENT_SECRET = Service Principal Client Secret created in the Tenant -ARM_SUBSCRIPTION_ID = The management subscription ID created in the Tenant -ARM_TENANT_ID = Tenant ID of the Azure Tenant that was used to create ESLZ - -![img](./media/clip_image042.jpg) - -* A Pull Request is either in progress or has completed and automatically merged into the main branch. - -![img](./media/clip_image044.png) - -* The Azure hierarchy that got created using ARM templates as part of the Enterprise-Scale setup, such as management groups, subscription organization as well as policy definitions, policy assignments and role assignments are hydrated and organized into Git: - -![Graphical user interface Description automatically generated with medium confidence](./media/clip_image046.jpg) - - -![Graphical user interface, application Description automatically generated](./media/clip_image048.jpg) - -* In each folder, you will find the ARM templates that were deployed at the scopes during the Enterprise-Scale setup. E.g., on the intermediate root group, you will find all policy definitions, and depending on the selection you made during the deployment, you will find resource templates in the platform subscriptions. Users can – whenever they are ready, start using these templates and bring their own templates to manage the platform using ARM templates and infrastructure as code. - -![Graphical user interface, application Description automatically generated](./media/clip_image050.jpg) - -## Operating the Azure platform using AzOps (Infrastructure as Code with GitHub Actions) - -When you have deployed Enterprise-Scale with GitHub integration, you will have a ready-to-go repository with integrated GitHub Actions containing all the ARM templates that were used during deployment, organized in the following way: - -* Management group tree structure represented as folders in Git - -* Subscriptions represented as folders in their respective management group folder in Git - -* Resource Groups represented as folders in their respective subscription folder in Git - -* Policy Definitions, Policy Set Definitions, Role Definitions, and Role Assignments as composite ARM resource templates partitioned at the folder representing the respective scope in Azure (management group, subscription) - -* Resources (e.g., virtual networks, Log Analytics workspace, Automation account etc.) represented as composite ARM resource templates into their respective resource group (folder) - -You can edit/update the existing ARM templates in your repository and GitHub actions will push (deploy) to the respective Azure scope. You can also author and bring your own ARM templates and deploy them to the respective Azure scope. - -The following section will demonstrate how one can operationalize the Enterprise-Scale platform using ARM templates, via the GitHub repository that got created using AzOps (GitHub Actions). - -### What is AzOps? - -AzOps is an opinionated CI/CD pipeline to operationalize the Azure *platform* and *landing zones* that enables organizations to focus on the ARM template development, and not having to deal with multiple deployment scripts targeting different Azure scopes. The organization and folder structure in Git is dynamically representing the Azure graph (management groups (parent, child relationships), and subscription organization), so the platform operators can easily determine at which *scope* they want to invoke the ARM template deployment by simply making a PR with the ARM template(s) and parameter files (optionally), and AzOps will invoke the deployment accordingly. - -Also, when there’s a new *scope* (management groups, subscriptions, and resource groups) being created, either explicitly via the pipeline – and also out of band (via Portal, CLI, PS etc.), AzOps will discover these and represent them correctly back into Git. - -### Create new Policy Assignment for validation - -Enterprise-Scale with its Policy Driven Governance principle relies heavily on Azure Policy to determine the goal state of the overall platform. As an example, this exercise will demonstrate how a developer can make a new policy assignment at the “Online” landing zone management group scope. - -1. In GitHub, navigate to your repository and click on the ‘azops’ folder. From here, navigate to your -online folder which represents the management group for all your online landing zones. - -![img](./media/clip_image052.jpg) - -2. Click on ‘Add file’, and ‘Create new file’. - -3. Name the file ‘locationAssignment.json’ - -4. Copy and paste the following ARM template json - -``` json -{ - "$schema": "https://schema.management.azure.com/schemas/2019-08-01/managementGroupDeploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "policyAssignmentEnforcementMode": { - "type": "string", - "allowedValues": [ - "Default", - "DoNotEnforce" - ], - "defaultValue": "DoNotEnforce", - "metadata": { - "description": "Input will determine if the policyAssignment should be enforced or not." - } - }, - "policyDefinitionId": { - "type": "string", - "defaultValue": "/providers/Microsoft.Authorization/policyDefinitions/e56962a6-4747-49cd-b67b-bf8b01975c4c", - "metadata": { - "description": "Provide the policyDefinition resourceId" - } - }, - "policyAssignmentName": { - "type": "string", - "defaultValue": "AllowedLocations" - }, - "policyDescription": { - "type": "string", - "defaultValue": "Policy to ringfence Azure regions." - }, - "listOfAllowedLocations": { - "type": "array", - "defaultValue": [ - "westeurope", - "northeurope" - ] - } - }, - "variables": {}, - "resources": [ - { - "type": "Microsoft.Authorization/policyAssignments", - "apiVersion": "2019-09-01", - "name": "[parameters('policyAssignmentName')]", - "identity": { - "type": "SystemAssigned" - }, - "location": "[deployment().location]", - "properties": { - "description": "[parameters('policyDescription')]", - "displayName": "[parameters('policyDescription')]", - "policyDefinitionId": "[parameters('policyDefinitionId')]", - "enforcementMode": "[parameters('policyAssignmentEnforcementMode')]", - "parameters": { - "listOfAllowedLocations": { - "value": "[parameters('listOfAllowedLocations')]" - } - } - } - } - ] -} -``` - -5. Examine the file and note that we are using default values for the parameters. You could modify these, or you could also provide a locationAssignment.parameters.json file to provide the parameters. - -6. On the ‘Commit new file’ option, select ‘Create a new branch for this commit and start a pull request’, and give it a name. - -![Graphical user interface, text, application, email Description automatically generated](./media/ESLZ-location-assignment-policy.JPG) - -7. Click ‘Propose new file' and on the next page, click 'Create Pull Request." A new Pull Request is being created which will trigger the Push workflow. Go to Actions to monitor the process. - -![Graphical user interface, text, application, chat or text message Description automatically generated](./media/clip_image056.jpg) - -8. Once completed, the pull request should automatically merge. - -9. In Azure portal, you can navigate to the -online management group and verify that the deployment resource got created and deployed successfully. Each deployment invoked via AzOps will have an ‘AzOps’ prefix. - -![Graphical user interface, text, application, email Description automatically generated](./media/clip_image058.jpg) - -10. Navigate to ‘Policies’ on the -online management group and verify that there’s a new assignment called ‘Policy to ring-fence Azure regions’. - -![Graphical user interface, text, application, email Description automatically generated](./media/clip_image060.jpg) - -11. Click on ‘Edit assignment’ to verify that the Policy is not being enforced but will only scan for compliance and validate resources per the policy rule defined in the policy definition. - -![Text Description automatically generated with low confidence](./media/clip_image062.jpg) - -Once the policy compliance scan has completed, you will get a compliance result for the policy you assigned to validate the effect is working as intended, before going to the next step to update the enforcement mode. I.e., this policy will prevent resources being created outside of the allowed locations specified. - -You can now merge the pull request and delete the branch. - -### Update a Policy Assignment to enforce - -In this exercise, we will modify the existing policy assignment to ensure the policy effect will be enforced. - -1. Navigate the locationAssignment.json file you placed into the -online folder, representing the online landing zone. - -2. Click on ‘Edit this file’ ![img](./media/clip_image063.png) - -3. Change the parameter “policyAssignmentEnforcementMode” default value to be ‘Default’. - -![Graphical user interface, text, application, email Description automatically generated](./media/clip_image065.jpg) - -4. On the ‘Commit changes’ dialogue box, select ‘Create a new branch for this commit and start a pull request’, and provide a branch name. Click ‘Propose changes’ and create the pull request - -![Graphical user interface, text, application, email Description automatically generated](./media/ESLZ-Update-location-assignment-policy.JPG) - -This will now start the AzOps push workflow and deploy the template with the updated property so that the policy effect will be enforced (in this case, deny resource creation outside of the ringfenced Azure regions). - -Once the job has completed, you can revisit the policy in Azure portal and see that the policy enforcement is set to ‘Enabled’. - -![Graphical user interface, text, application, email Description automatically generated](./media/clip_image069.jpg) - -You can now merge the pull request and delete the branch. - -### Create new Role Assignment on a landing zone - -To grant a user, a group, or a service principal access to a landing zone (subscription), you can use the following ARM template where you provide the principalId (object id of the user, group, or service principal) as input to the parameter, and place the template into the subscription folder into your landing zone management group(s). - -Replace Provide-Principal-Id with Id of the principal. - -```json -{ - "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "principalId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Provide the objectId of the principal (user, group, SPN, managed identity etc.) that will be granted RBAC at scope." - } - }, - "roleDefinitionId": { - "type": "string", - "defaultValue": "b24988ac-6180-42a0-ab88-20f7382dd24c", - "metadata": { - "description": "Provide the id of the built-in roleDefinition. Default is 'Contributor'." - } - } - }, - "resources": [ - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2017-09-01", - "name": "[guid(parameters('principalId'))]", - "properties": { - "principalId": "[parameters('principalId')]", - "roleDefinitionId": "[concat('/providers/Microsoft.Authorization/roleDefinitions/', parameters('roleDefinitionId'))]" - } - } - ] -} -``` +Please refer to [Azure landing zone portal deployment for Platform DevOps and Automation](./Deploying-ALZ-Platform-DevOps) diff --git a/docs/wiki/Deploying-Enterprise-Scale-Pre-requisites.md b/docs/wiki/Deploying-Enterprise-Scale-Pre-requisites.md index 6e79e51702..f927ee5c45 100644 --- a/docs/wiki/Deploying-Enterprise-Scale-Pre-requisites.md +++ b/docs/wiki/Deploying-Enterprise-Scale-Pre-requisites.md @@ -1,2 +1,3 @@ -## This page has moved -Please refer to [Azure landing zone portal accelerator Pre-requisites](./Deploying-ALZ-Pre-requisites) \ No newline at end of file +# This page has moved + +Please refer to [Azure landing zone portal accelerator Pre-requisites](./Deploying-ALZ-Pre-requisites) diff --git a/docs/wiki/Deploying-Enterprise-Scale-VWAN.md b/docs/wiki/Deploying-Enterprise-Scale-VWAN.md index bf8acf7a54..b7d5f89c70 100644 --- a/docs/wiki/Deploying-Enterprise-Scale-VWAN.md +++ b/docs/wiki/Deploying-Enterprise-Scale-VWAN.md @@ -1,3 +1,3 @@ -## This page has moved +# This page has moved -Please refer to [Azure landing zone portal accelerator deployment with Azure VWAN network topology](./Deploying-ALZ-VWAN) \ No newline at end of file +Please refer to [Azure landing zone portal accelerator deployment with Azure VWAN network topology](./Deploying-ALZ-VWAN) diff --git a/docs/wiki/Deploying-Enterprise-Scale.md b/docs/wiki/Deploying-Enterprise-Scale.md index 5660b62eef..6c0496689b 100644 --- a/docs/wiki/Deploying-Enterprise-Scale.md +++ b/docs/wiki/Deploying-Enterprise-Scale.md @@ -1,3 +1,3 @@ -## This page has moved +# This page has moved -Please refer to [Deploy Azure landing zone portal accelerator](./Deploying-ALZ) \ No newline at end of file +Please refer to [Deploy Azure landing zone portal accelerator](./Deploying-ALZ) diff --git a/docs/wiki/FAQ.md b/docs/wiki/FAQ.md index 2ad3247d48..9d2ab1fc17 100644 --- a/docs/wiki/FAQ.md +++ b/docs/wiki/FAQ.md @@ -37,7 +37,7 @@ We then work with the Azure Policy and associated engineering teams to continuou ## Where can I see the policy definitions used by the enterprise-scale landing zones reference implementation? -You can find a list of policy definitions here: [Policies included in enterprise-scale landing zones reference implementations](https://github.com/Azure/Enterprise-Scale/blob/main/docs/ESLZ-Policies.md) +You can find a list of policy definitions here: [Policies included in enterprise-scale landing zones reference implementations](./ALZ-Policies) We also add changes to our [What's New? wiki page](https://github.com/Azure/Enterprise-Scale/wiki/Whats-new). diff --git a/docs/wiki/Home.md b/docs/wiki/Home.md index 8202c2ac38..2f8c4ff2c4 100644 --- a/docs/wiki/Home.md +++ b/docs/wiki/Home.md @@ -1,32 +1,7 @@ -# Enterprise-Scale Landing Zones User Guide +# Azure landing zones User Guide -The Enterprise-Scale Landing Zones User Guide aims to provide comprehensive end-to-end documentation for the Enterprise-Scale deployment and configuration experience to accelerate both adoption and deployment. +> **NOTE:** _Enterprise-Scale is now Azure landing zones_ -## Navigation +This user guide aims to provide comprehensive end-to-end documentation for the Azure landing zone deployment and configuration experience to accelerate both adoption and deployment. -* [What's New?](https://github.com/Azure/Enterprise-Scale/wiki/Whats-new) -* [Community Calls](https://github.com/Azure/Enterprise-Scale/wiki/Community-Calls) -* [Azure Landing Zones Deprecated Policies](https://github.com/Azure/Enterprise-Scale/wiki/ALZ-Deprecated-Services) -* [What is Enterprise-Scale?](https://github.com/Azure/Enterprise-Scale/wiki/What-is-Enterprise-Scale) - * [What is Enterprise-Scale reference implementation?](https://github.com/Azure/Enterprise-Scale/wiki/What-is-Enterprise-Scale#what-is-enterprise-scale-reference-implementation) - * [Pricing](https://github.com/Azure/Enterprise-Scale/wiki/What-is-Enterprise-Scale#pricing) - * [What if I already have an existing Azure footprint](https://github.com/Azure/Enterprise-Scale/wiki/What-is-Enterprise-Scale#what-if-i-already-have-an-existing-azure-footprint) -* [How Enterprise-Scale Works](https://github.com/Azure/Enterprise-Scale/wiki/How-Enterprise-Scale-Works) - * [Enterprise-Scale design principles](https://github.com/Azure/Enterprise-Scale/wiki/How-Enterprise-Scale-Works#enterprise-scale-design-principles) - * [Separating platform and landing zones](https://github.com/Azure/Enterprise-Scale/wiki/How-Enterprise-Scale-Works#separating-platform-and-landing-zones) - * [Enterprise-Scale Management Group Structure](https://github.com/Azure/Enterprise-Scale/wiki/How-Enterprise-Scale-Works#enterprise-scale-management-group-structure) - * [What happens when you deploy Enterprise-Scale?](https://github.com/Azure/Enterprise-Scale/wiki/How-Enterprise-Scale-Works#what-happens-when-you-deploy-enterprise-scale) -* Deploying Azure landing zone portal accelerator (Enterprise-Scale) - * [Pre-requisites](https://github.com/Azure/Enterprise-Scale/wiki/Deploying-ALZ-Pre-requisites) - * [Telemetry Tracking Using Customer Usage Attribution (PID)](https://github.com/Azure/Enterprise-Scale/wiki/Deploying-ALZ-CustomerUsage) - * [Deploy without hybrid connectivity to on-premises](https://github.com/Azure/Enterprise-Scale/wiki/Deploying-ALZ-Foundation) - * [Deploy with a hub and spoke based network topology](https://github.com/Azure/Enterprise-Scale/wiki/Deploying-ALZ-HubAndSpoke) - * [Deploy with an Azure Virtual WAN based network topology](https://github.com/Azure/Enterprise-Scale/wiki/Deploying-ALZ-VWAN) - * [Deploy for Small Enterprises](https://github.com/Azure/Enterprise-Scale/wiki/Deploying-ALZ-BasicSetup) - * [Operating the Azure platform using AzOps (Infrastructure as Code with GitHub Actions)](https://github.com/Azure/Enterprise-Scale/wiki/Deploying-ALZ-Platform-DevOps#operating-the-azure-platform-using-azops-infrastructure-as-code-with-github-actions) -* [Create subscriptions / landing zones using AzOps](https://github.com/Azure/Enterprise-Scale/wiki/Create-Landingzones) - * [Create landing zones (subscription) using AzOps](https://github.com/Azure/Enterprise-Scale/wiki/Create-Landingzones#create-landing-zones-subscription-using-azops) - * [Pre-requisites](https://github.com/Azure/Enterprise-Scale/wiki/Create-Landingzones.md#pre-requisites) - * [Enable Service Principal to create landing zones](https://github.com/Azure/Enterprise-Scale/wiki/Create-Landingzones#enable-service-principal-to-create-landing-zones) - * [ARM template repository](https://github.com/Azure/Enterprise-Scale/wiki/Create-Landingzones#arm-template-repository) - * [Create a new landing zone (subscriptions)](https://github.com/Azure/Enterprise-Scale/wiki/Create-Landingzones#create-a-new-landing-zone-subscriptions) \ No newline at end of file +Please use the navigation links to browse our content... diff --git a/docs/wiki/How-Enterprise-Scale-Works.md b/docs/wiki/How-Enterprise-Scale-Works.md index e546db8b35..0e880302c5 100644 --- a/docs/wiki/How-Enterprise-Scale-Works.md +++ b/docs/wiki/How-Enterprise-Scale-Works.md @@ -13,7 +13,7 @@ - [Enterprise-Scale Management Group Structure](#enterprise-scale-management-group-structure) - [What happens when you deploy Enterprise-Scale?](#what-happens-when-you-deploy-enterprise-scale) ------- +------ This section describes at a high level how Enterprise-Scale reference implementation works. Your landing zones are the output of a multi-subscription environment for all your Azure services, where compliance, guardrails, security, networking, and identity is provided at scale by the platform. ## Enterprise-Scale design principles @@ -86,7 +86,7 @@ By default, all recommended settings and resources recommendations are enabled a - A scalable Management Group hierarchy aligned to core platform capabilities, allowing you to operationalize at scale using centrally managed Azure RBAC and Azure Policy where platform and workloads have clear separation. -- Azure Policies that will enable autonomy for the platform and the landing zones. The full list of policies leveraged by Enterprise-Scale, their intent, assignment scope, and life-cycle can be [viewed here](https://github.com/Azure/Enterprise-Scale/blob/main/docs/ESLZ-Policies.md). +- Azure Policies that will enable autonomy for the platform and the landing zones. The full list of policies leveraged by Enterprise-Scale, their intent, assignment scope, and life-cycle can be [viewed here](./ALZ-Policies). - An Azure subscription dedicated for **Management**, which enables core platform capabilities at scale using Azure Policy such as: - A Log Analytics workspace and an Automation account diff --git a/docs/wiki/migrate-alz-policies-to-builtin.md "b/docs/wiki/Migrate-ALZ-Policies-to-Built\342\200\220in.md" similarity index 100% rename from docs/wiki/migrate-alz-policies-to-builtin.md rename to "docs/wiki/Migrate-ALZ-Policies-to-Built\342\200\220in.md" diff --git a/docs/wiki/Update-ALZ-Custom-Policies-to-Latest.md b/docs/wiki/Update-ALZ-Custom-Policies-to-Latest.md new file mode 100644 index 0000000000..17117de862 --- /dev/null +++ b/docs/wiki/Update-ALZ-Custom-Policies-to-Latest.md @@ -0,0 +1,280 @@ +# Introduction + +This article describes how to update ALZ custom policies and policy initiatives to latest versions of ALZ custom policies. The guidance provided in this document describes manual steps for performing the update, based on a set of specific policies and initiatives, with PowerShell. + +> Note: If you are already managing Azure Policies through Infrastructure as Code (IaC), you may not want to be updating your Azure Policies outside of your pipeline. This article assumes a manual approach to updating Azure landing zone (ALZ) policies. + +> Important: To carry out the instructions below, the operator will require Resource Policy Contributor permissions at the root of the ALZ management group hierarchy. + +## Detect updates to policy + +1. To determine if there has been updates to ALZ your first reference should be [What's New](https://github.com/Azure/Enterprise-Scale/wiki/Whats-new). Any updates to policies or other ALZ related artifacts will be reflected here upon release. An example of what that will look like can be seen [here](https://github.com/Azure/Enterprise-Scale/wiki/Whats-new#policy). + +2. Alternatively, [Azure Governance Visualizer](https://github.com/JulianHayward/Azure-MG-Sub-Governance-Reporting) can be run in your environment and reveal information about the current state of policies and policy assignments. Part of the output of Azure Governance Visualizer is Azure Landing Zones (ALZ) Policy Version Checker which will allows you to see all **outDated** ALZ policies in your environment (see figure 1). +![AzGovViz-ALZ-Policy-Checker](media/AzGovViz-ALZ-Policy-outDated.png) +*Figure 1: Azure Governance Visualizer filtering on outDated ALZ policies* + +> Note that Azure Governance Visualizer requires permissions in your tenant as described [here](https://github.com/JulianHayward/Azure-MG-Sub-Governance-Reporting#permissions-overview) + +## Updating scenarios + +These are the following scenarios for ALZ custom policies being updated to latest versions of the custom ALZ policies, listed in increasing order of complexity: + +1. One or more ALZ custom policies, whether assigned or not at one or more scopes in your Azure estate, is superseded by a newer version of that same ALZ custom policy. The process for managing this is described in [Updating one or more ALZ custom policy to newer ALZ custom policies](#updating-one-or-more-alz-custom-policies-to-newer-alz-custom-policy). + +2. One or more ALZ custom policies, assigned at one or more scopes in your Azure estate, is superseded by a newer version of the same ALZ custom policy with **updated parameters**. The process for managing this is described in [Updating one or more ALZ custom policies to a newer ALZ custom policy with updated parameters](#updating-one-or-more-alz-custom-policies-to-newer-alz-custom-policy-with-updated-parameters) + +3. One or more ALZ custom policies, assigned via ALZ custom policy initiative, are superseded by a newer version of the same ALZ custom policy(s) with **updated parameters**. The process for managing this is described in [Updating ALZ custom policies in ALZ custom policy initiative to newer ALZ custom policies](#updating-alz-custom-policies-in-alz-custom-policy-initiative-to-newer-alz-custom-policies) + +### Updating one or more ALZ custom policies to newer ALZ custom policy + +For this scenario we will use the ALZ custom policy *Deploy Diagnostic Settings for WVD Host Pools to Log Analytics workspace*. + +Considering no parameters have changed, this is a simple exercise that consists of replacing the policy definition content with the latest policy definition. While it is possible to update the policy definition via the portal GUI, there are some properties than can't be updated, like version. To minimize errors and include all updated policy definition properties, we will be updating this policy via a PowerShell script. + +Before we begin, we need to identify the policy definition name and location to be used in our PowerShell script below. + +- Go to [Azure Portal](https://portal.azure.com) +- Open Policy +- Go to Definitions and in Search, find the ALZ custom policy. + + ![alz-custom-policy-def-search](media/1.1.update-alz-custom-policy-def-search.png) + +- Click on the hyperlink for the policy definition +- Capture the policy definition name and scope from `Definition ID` and `Definition location`. In this example, the `Definition ID` is `/providers/Microsoft.Management/managementGroups/MTB/providers/Microsoft.Authorization/policyDefinitions/Deploy-Diagnostics-WVDHostPools` with a policy definition name of **Deploy-Diagnostics-WVDHostPools** and a scope of **MTB**. The policy definition name is the set of characters following the last `/`. Both the policy definition name and scope will be used in the PowerShell script below. + + ![alz-custom-policy-def-name](media/1.2.update-alz-custom-policy-def-name.png) + +- To update to the latest version of the definition, we will use the policy definition templates available in https://github.com/Azure/Enterprise-Scale/tree/main/src/resources/Microsoft.Authorization/policyDefinitions as described in the following. + +- Go to https://portal.azure.com +- Start an Azure Cloud Shell with PowerShell engine +- Execute the following PowerShell script ([disclaimer](https://github.com/Azure/Enterprise-Scale/blob/main/SUPPORT.md)) for each ALZ custom policy definition: + - Before executing the following PowerShell script, update the first two variables: + - `$policyDefinitionName` + - `$policyDefinitionLocation` + + ```posh + $policyDefinitionName = "Deploy-Diagnostics-WVDHostPools" # <-- Replace with policy definition name found earlier + $policyDefinitionLocation = "MTB" # <-- Replace with Definition location found earlier + $policyDefinitionPath = "./$($policyDefinitionName).json" + Invoke-WebRequest -Uri "https://raw.githubusercontent.com/Azure/Enterprise-Scale/main/src/resources/Microsoft.Authorization/policyDefinitions/$($policyDefinitionName).json" -OutFile $policyDefinitionPath + $policyDef = Get-Content $policyDefinitionPath | ConvertFrom-Json -Depth 100 + $policyName = $policyDef.name + $displayName = $policyDef.properties.displayName + $description = $policyDef.properties.description + $mode = $policyDef.properties.mode + $metadata = $policyDef.properties.metadata | ConvertTo-Json -Depth 100 + $parameters = $policyDef.properties.parameters | ConvertTo-Json -Depth 100 + $policyRule = $policyDef.properties.policyRule | ConvertTo-Json -Depth 100 + $policyRule = $policyRule.Replace('[[', '[') + Set-AzPolicyDefinition -Name $policyName -DisplayName $displayname -Description $description -Policy $policyRule -Mode $mode -Metadata $metadata -Parameter $parameters -ManagementGroupName $policyDefinitionLocation + ``` + +> Note that if you decide on another approach from the script above, there are a number of double brackets ('[[') in the file. These need to be replaced with single brackets before the policy set definition is valid syntax. + +### Updating one or more ALZ custom policies to newer ALZ custom policy with updated parameters + +For this scenario, we will use the ALZ custom policy *Deploy Diagnostic Settings for WVD Host Pools to Log Analytics workspace*. Even though this policy doesn't have any updated parameters, we will walk through the steps as though it does. + +- Go to [Azure Portal](https://portal.azure.com) +- Open Policy +- Go to Definitions and in Search, find the ALZ custom policy. + + ![alz-custom-policy-def-search](media/1.1.update-alz-custom-policy-def-search.png) + +- Click on the hyperlink for the policy definition + +- To determine if the policy is assigned at any scope in the ALZ management group structure start by getting the policy definition ID + - Capture the policy definition name and scope from `Definition ID` and `Definition location`. In this example, the `Definition ID` is `/providers/Microsoft.Management/managementGroups/MTB/providers/Microsoft.Authorization/policyDefinitions/Deploy-Diagnostics-WVDHostPools` with a policy definition name of **Deploy-Diagnostics-WVDHostPools** and a scope of **MTB**. The policy definition name is the set of characters following the last `/`. Both the policy definition name and scope will be used in the PowerShell script below. + + ![alz-custom-policy-def-name](media/1.2.update-alz-custom-policy-def-name.png) + +- Since there is no easy way to get the various scopes a policy is assigned to, go to Azure Resource Graph Explorer +- Ensure that scope for the query is Directory and then execute the following kusto query: + + ```kusto + PolicyResources | + where kind =~ 'policyassignments' and tostring(properties.policyDefinitionId) =~ '/providers/Microsoft.Management/managementGroups/MTB/providers/Microsoft.Authorization/policyDefinitions/Deploy-Diagnostics-WVDHostPools' + | extend + assignmentScope = tostring(properties.scope), + assignmmentNotScopes = tostring(properties.notScopes), + assignmmentParameters = tostring(properties.parameters) + | project assignmentScope, + assignmmentNotScopes, + assignmmentParameters + ``` + +- The above command will give a result similar to what is shown below + + ![alz-custom-policy-assignments](media/2.1.update-alz-custom-policy-assignments.png) + +- Record the assignment scopes so you can recreate the assignments later +- As can be seen this particular policy is assigned with only a single DINE effect parameter at the following levels in the management group structure: + - MTB/MTB-landingzones + - MTB/MTB-sandboxes + +> Note that if more complex parameters are assigned to a policy which is to be updated, those should be noted down. In that respect the possibility to download the query results as CSV could be leveraged. + +- Switch from Azure Resource Graph Explorer back to the Policy Assignments view +- Change the scope to include the scopes determined in the previous step and search for the relevant policy + + ![alz-delete-policy-assignments](media/2.2.update-alz-custom-policy-delete-assignments.png) + +- For each assignment, click the ellipsis and select Delete Assignment. +- Once all policy assignments are deleted, go to the Definitions pane, search for the definition. Once found click the ellipsis and choose Delete Policy Definition + + ![alz-custom-policy-def-search](media/2.3.update-alz-custom-policy-search.png) + +> Important: Record the **Definition location** of the Policy Definition as it will be used in (`$policyDefinitionLocation`) the script below. + +- To update to the latest version of the definition, we will use the policy definition templates available in https://github.com/Azure/Enterprise-Scale/tree/main/src/resources/Microsoft.Authorization/policyDefinitions as described in the following. + +- Go to https://portal.azure.com +- Start an Azure Cloud Shell with PowerShell engine +- Execute the following PowerShell script ([disclaimer](https://github.com/Azure/Enterprise-Scale/blob/main/SUPPORT.md)) for each ALZ custom policy definition: + - Before executing the following PowerShell script, update the first two variables: + - `$policyDefinitionName` + - `$policyDefinitionLocation` + + ```posh + $policyDefinitionName = "Deploy-Diagnostics-WVDHostPools" # <-- Replace with policy definition name found earlier + $policyDefinitionLocation = "MTB" # <-- Replace with Definition location found earlier + $policyDefinitionPath = "./$($policyDefinitionName).json" + Invoke-WebRequest -Uri "https://raw.githubusercontent.com/Azure/Enterprise-Scale/main/src/resources/Microsoft.Authorization/policyDefinitions/$($policyDefinitionName).json" -OutFile $policyDefinitionPath + $policyDef = Get-Content $policyDefinitionPath | ConvertFrom-Json -Depth 100 + $policyName = $policyDef.name + $displayName = $policyDef.properties.displayName + $description = $policyDef.properties.description + $mode = $policyDef.properties.mode + $metadata = $policyDef.properties.metadata | ConvertTo-Json -Depth 100 + $parameters = $policyDef.properties.parameters | ConvertTo-Json -Depth 100 + $policyRule = $policyDef.properties.policyRule | ConvertTo-Json -Depth 100 + $policyRule = $policyRule.Replace('[[', '[') + New-AzPolicyDefinition -Name $policyName -DisplayName $displayname -Description $description -Policy $policyRule -Mode $mode -Metadata $metadata -Parameter $parameters -ManagementGroupName $policyDefinitionLocation + ``` + +> Note that if you decide on another approach from the script above, there are a number of double brackets ('[[') in the file. These need to be replaced with single brackets before the policy set definition is valid syntax. + +- To assign *Deploy Diagnostic Settings for AVD Host Pools to Log Analytics workspace* policy, search for that policy definition. Once found click the ellipsis and choose Assign + + ![alz-custom-policy-def-search](media/2.4.update-alz-custom-policy-search.png) + +> Note how the display name changed from WVD to AVD. + +- Set relevant parameters which were captured earlier. + +### Updating ALZ custom policies in ALZ custom policy initiative to newer ALZ custom policies + +For this scenario we will use the ALZ custom initiative _Deploy Diagnostic Settings to Azure Services_ which is leveraging quite a large number of ALZ custom policies to apply diagnostics settings for various resources. As the initiative is updated at [source](https://github.com/Azure/Enterprise-Scale/tree/main/src/resources/Microsoft.Authorization/policySetDefinitions), the easiest way to achieve the migration in a manual way is to pull the newest version of the initiative from there. + +- Go to https://portal.azure.com +- Open Policy +- Go to Definitions and in Search find the ALZ custom policy initiative. + + ![alz-custom-initiative-def-search](media/alz-update-initiative-with-builtin-01.png) + +- Click on the hyperlink for the initiative definition +- To determine where the initiative is assigned at any scope in the ALZ management group structure start by getting the initiative **Definition ID**. Record the initiative name (/providers/Microsoft.Management/managementGroups/**Contoso**/providers/Microsoft.Authorization/policySetDefinitions/***Deploy-Diagnostics-LogAnalytics***) and location as it will be used in the PowerShell script below. + + ![alz-custom-initiative-def-name](media/alz-update-initiative-with-builtin-02.png) + +- Since there is no easy way to get the various scopes an initiative is assigned to, go to Azure Resource Graph Explorer +- Ensure that scope for the query is Directory and then execute the following kusto query: + + ```kusto + PolicyResources | + where kind =~ 'policyassignments' and tostring(properties.policyDefinitionId) =~ '/providers/Microsoft.Management/managementGroups/contoso/providers/Microsoft.Authorization/policySetDefinitions/Deploy-Diagnostics-LogAnalytics' + | extend + assignmentScope = tostring(properties.scope), + assignmmentNotScopes = tostring(properties.notScopes), + assignmmentParameters = tostring(properties.parameters) + | project assignmentScope, + assignmmentNotScopes, + assignmmentParameters + ``` + +- The above command will give a result similar to what is shown below + + ![alz-custom-initiative-assignments](media/alz-update-initiative-with-builtin-03.png) + +- Record the assignment scopes so you can recreate the assignments later +- As can be seen this particular initiative is assigned with only a single parameter at the following levels in the management group structure + - Contoso/ + +> Note that the provided example has a simple parameter set. Even though this initiative has over 60 parameters, the other parameters are utilizing the **Default value**. If more complex parameters are assigned to a policy which is to be migrated those should be noted down. In that respect the possibility to download the query results as CSV could be leveraged. + +- Switch from Azure Resource Graph Explorer back to the Policy view +- Change the scope to include the scope described above, and search for the relevant initiative + + ![alz-delete-initiative-assignments](media/alz-update-initiative-with-builtin-04.png) + +- For each assignment, click the ellipsis and select Delete Assignment +- Once all initiative assignments are deleted, go to the Definitions pane, search for the initiative definition + +> Note: It is highly recommended you update all the ALZ custom policies to the latest version before continuing. The script below has a variable, `$updateCustomALZPolicies`, to update all of the ALZ custom policy definitions if set to `$true`. + +- Once found click the ellipsis and choose Delete Policy Initiative Definition + + ![alz-custom-initiative-def-search](media/alz-update-initiative-with-builtin-01.png) + +> Important: Record the **Definition location** of the Policy Initiative Definition as it will be used in (`$policySetDefinitionLocation`) the script below. + +- To create the new version of the initiative, while this is possible to do in the portal through the portal GUI, with the number of policies to be included it would be a huge task. Instead, we suggest the use of the templates available in https://github.com/Azure/Enterprise-Scale/tree/main/src/resources/Microsoft.Authorization/policySetDefinitions to create the new policy initiative definition and update the custom ALZ policy definitions as described in the following. + +- Go to https://portal.azure.com +- Start an Azure Cloud Shell with PowerShell engine +- Before executing the following PowerShell script ([disclaimer](https://github.com/Azure/Enterprise-Scale/blob/main/SUPPORT.md)), update the first three variables: + - `$updateCustomALZPolicies` + - `$policySetDefinitionName` + - `$policySetDefinitionLocation` + + ```posh + $updateCustomALZPolicies = $true # <-- $false = don't update the policy definitions + $policySetDefinitionName = "Deploy-Diagnostics-LogAnalytics" # <-- Replace with policy definition name found earlier + $policySetDefinitionLocation = "Contoso" # <-- Replace with Definition location found earlier + $policySetDefinitionPath = "./$($policySetDefinitionName).json" + Invoke-WebRequest -Uri https://raw.githubusercontent.com/Azure/Enterprise-Scale/main/src/resources/Microsoft.Authorization/policySetDefinitions/$($policySetDefinitionName).json -OutFile $policySetDefinitionPath + $policySetDef = Get-Content $policySetDefinitionPath | ConvertFrom-Json -Depth 100 + + # Update all ALZ custom policy definitions first + if ($updateCustomALZPolicies) { + foreach ($policyDefId in $policySetDef.properties.policyDefinitions.policyDefinitionId) { + if ($policyDefId -match '(\/\w+\/\w+\.\w+\/\w+\/)(\w+)(\/.+)') { + $policyDefinitionName = $policyDefId.substring($policyDefId.lastindexof('/') + 1) + $policyDefinitionPath = "./$($policyDefinitionName).json" + Invoke-WebRequest -Uri "https://raw.githubusercontent.com/Azure/Enterprise-Scale/main/src/resources/Microsoft.Authorization/policyDefinitions/$($policyDefinitionName).json" -OutFile $policyDefinitionPath + $policyDef = Get-Content $policyDefinitionPath | ConvertFrom-Json -Depth 100 + $policyName = $policyDef.name + $displayName = $policyDef.properties.displayName + $description = $policyDef.properties.description + $mode = $policyDef.properties.mode + $metadata = $policyDef.properties.metadata | ConvertTo-Json -Depth 100 + $parameters = $policyDef.properties.parameters | ConvertTo-Json -Depth 100 + $policyRule = $policyDef.properties.policyRule | ConvertTo-Json -Depth 100 + $policyRule = $policyRule.Replace('[[', '[') + New-AzPolicyDefinition -Name $policyName -DisplayName $displayname -Description $description -Policy $policyRule -Mode $mode -Metadata $metadata -Parameter $parameters -ManagementGroupName $policyDefinitionLocation + } + } + } + # End of updating all ALZ custom policy definitions + + $policyName = $policySetDef.name + $displayName = $policySetDef.properties.displayName + $description = $policySetDef.properties.description + $metadata = $policySetDef.properties.metadata | ConvertTo-Json -Depth 100 + $parameters = $policySetDef.properties.parameters | ConvertTo-Json -Depth 100 + $policyDefinitions = ConvertTo-Json -InputObject @($policySetDef.properties.policyDefinitions) -Depth 100 + $policyDefinitions = $policyDefinitions.Replace('[[', '[') + $policyDefinitions = $policyDefinitions -replace '(\/\w+\/\w+\.\w+\/\w+\/)(\w+)(\/.+)', "`${1}$policyDefinitionLocation`${3}" + New-AzPolicySetDefinition -Name $policyName -DisplayName $displayname -Description $description -PolicyDefinition $policyDefinitions -Metadata $metadata -Parameter $parameters -ManagementGroupName $policyDefinitionLocation + ``` + +> Note that if you decide on another approach from the script above, there are a number of double square brackets ('[[') in the file. These need to be replaced with single square brackets before the policy set definition is valid syntax. + +- After running the above script go to the Definitions pane, and search for the initiative definition. Note that the initiative may take a while to show in the portal + + ![alz-custom-initiative-def-search](media/alz-update-initiative-with-builtin-01.png) + +- When the initiative materializes, click the ellipsis and choose Assign +- Set relevant parameters for the initiative, then assign the policy to the scopes previously determined diff --git a/docs/wiki/What-is-Enterprise-Scale.md b/docs/wiki/What-is-Enterprise-Scale.md index 9e6fbba372..259ad3b4a8 100644 --- a/docs/wiki/What-is-Enterprise-Scale.md +++ b/docs/wiki/What-is-Enterprise-Scale.md @@ -59,4 +59,4 @@ Therefore it is important to complete the design process following the Enterpris Enterprise-Scale reference implementation will meet you where you are, and the design has catered for existing subscriptions and workloads in Azure. -See the following [article](https://docs.microsoft.com/en-us/azure/cloud-adoption-framework/ready/enterprise-scale/transition) to learn more how you can transition into Enterprise-Scale. \ No newline at end of file +See the following [article](https://docs.microsoft.com/azure/cloud-adoption-framework/ready/enterprise-scale/transition) to learn more how you can transition into Enterprise-Scale. \ No newline at end of file diff --git a/docs/wiki/Whats-new.md b/docs/wiki/Whats-new.md index b2a555f171..b9bc07d62d 100644 --- a/docs/wiki/Whats-new.md +++ b/docs/wiki/Whats-new.md @@ -2,7 +2,7 @@ - [In this Section](#in-this-section) - [Updates](#updates) - + - [January 2023](#january-2023) - [December 2022](#december-2022) - [November 2022](#november-2022) - [October 2022](#october-2022) @@ -49,14 +49,50 @@ This article will be updated as and when changes are made to the above and anyth Here's what's changed in Enterprise Scale/Azure Landing Zones: +### January 2023 + +#### Policy + +- Updated `Deploy-SQLVulnerabilityAssessments.json` policy to use Storage Account Contributor for storing the logs. +- Updated the same policy parameter description for email recipients explaining string type and how to format input. +- Fix typo in Deny-MachineLearning-PublicAccessWhenBehindVnet.json. + ### December 2022 +#### Docs + +- Migrated the following pages to the [Enterprise-Scale Wiki](https://github.com/Azure/Enterprise-Scale/wiki/) + + | Original URL | New URL | + | --- | --- | + | [docs/ESLZ-Policies.md](https://github.com/Azure/Enterprise-Scale/blob/main/docs/ESLZ-Policies.md) | [wiki/ALZ-Policies](https://github.com/Azure/Enterprise-Scale/wiki/ALZ-Policies) | + | [docs/EnterpriseScale-Architecture.md](https://github.com/Azure/Enterprise-Scale/blob/main/docs/EnterpriseScale-Architecture.md) | [wiki/ALZ-Architecture](https://github.com/Azure/Enterprise-Scale/wiki/ALZ-Architecture) | + | [docs/EnterpriseScale-Contribution.md](https://github.com/Azure/Enterprise-Scale/blob/main/docs/EnterpriseScale-Contribution.md) | [wiki/ALZ-Contribution](https://github.com/Azure/Enterprise-Scale/wiki/ALZ-Contribution) | + | [docs/EnterpriseScale-Deploy-landing-zones.md](https://github.com/Azure/Enterprise-Scale/blob/main/docs/EnterpriseScale-Deploy-landing-zones.md) | [wiki/ALZ-Deploy-landing-zones](https://github.com/Azure/Enterprise-Scale/wiki/ALZ-Deploy-landing-zones) | + | [docs/EnterpriseScale-Deploy-reference-implentations.md](https://github.com/Azure/Enterprise-Scale/blob/main/docs/EnterpriseScale-Deploy-reference-implentations.md) | [wiki/ALZ-Deploy-reference-implementations](https://github.com/Azure/Enterprise-Scale/wiki/ALZ-Deploy-reference-implementations) | + | [docs/EnterpriseScale-Deploy-workloads.md](https://github.com/Azure/Enterprise-Scale/blob/main/docs/EnterpriseScale-Deploy-workloads.md) | [wiki/ALZ-Deploy-workloads](https://github.com/Azure/Enterprise-Scale/wiki/ALZ-Deploy-workloads) | + | [docs/EnterpriseScale-Known-Issues.md](https://github.com/Azure/Enterprise-Scale/blob/main/docs/EnterpriseScale-Known-Issues.md) | [wiki/ALZ-Known-Issues](https://github.com/Azure/Enterprise-Scale/wiki/ALZ-Known-Issues) | + | [docs/EnterpriseScale-Roadmap.md](https://github.com/Azure/Enterprise-Scale/blob/main/docs/EnterpriseScale-Roadmap.md) | [wiki/ALZ-Roadmap](https://github.com/Azure/Enterprise-Scale/wiki/ALZ-Roadmap) | + | [docs/EnterpriseScale-Setup-aad-permissions.md](https://github.com/Azure/Enterprise-Scale/blob/main/docs/EnterpriseScale-Setup-aad-permissions.md) | [wiki/ALZ-Setup-aad-permissions](https://github.com/Azure/Enterprise-Scale/wiki/ALZ-Setup-aad-permissions) | + | [docs/EnterpriseScale-Setup-azure.md](https://github.com/Azure/Enterprise-Scale/blob/main/docs/EnterpriseScale-Setup-azure.md) | [wiki/ALZ-Setup-azure](https://github.com/Azure/Enterprise-Scale/wiki/ALZ-Setup-azure) | + +- Updated the guidance for contributing to the [Azure/Enterprise-Scale](https://github.com/Azure/Enterprise-Scale/) repository + +#### Tooling + +- Added ALZ Custom RBAC Role Definitions, as listed [here](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/identity-access-landing-zones#rbac-recommendations) to ALZ Portal Experience. Fixing [#1079](https://github.com/Azure/Enterprise-Scale/issues/1079) + #### Policy - Updated "**Deploy Diagnostic Settings to Azure Services**" initiative replacing deprecated policy for diagnostic settings on Storage Account - Removed all exclusions (parameters) from the Microsoft Cloud Security Benchmark (currently Azure Security Benchmark) initiative assignment to standardize across reference architectures and align with best practice. Impacted assignment: Deploy-ASC-Monitoring - Updated "**Deploy Diagnostic Settings for Data Factory to Log Analytics workspace" to include new categories of: `SandboxPipelineRuns` & `SandboxActivityRuns` +- Add missing `minimalSeverity` parameter to `Deploy-ASC-SecurityContacts` Policy Definition + +#### Tooling + +- Removed `ActivityLog` Solution as an option to be deployed into the Log Analytics Workspace. As this has been superseded by the Activity Log Insights Workbook, as documented [here.](https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log-insights) ### November 2022 @@ -100,11 +136,11 @@ Impacted assignment: Deploy-ASC-Monitoring - Added missing Zones for **"WebPubSub"** and **"azure-devices-provisioning"**, so Initiative Assignment works correctly - Minor correction related to **ASR Private DNS Zone variable**, so Initiative Assignment works correctly - Conversion of **"Azure Batch"** Private DNS Zone (from regional to global), to properly align with latest respective documentation and functionality -- Renamed Azure DDoS Standard Protection references to [Azure DDoS Network Protection](https://learn.microsoft.com/en-us/azure/ddos-protection/ddos-protection-sku-comparison#ddos-network-protection). +- Renamed Azure DDoS Standard Protection references to [Azure DDoS Network Protection](https://learn.microsoft.com/en-us/azure/ddos-protection/ddos-protection-sku-comparison#ddos-network-protection). - Incremented version for policy Deploy-DDoSProtection from "version":"1.0.0" to "version": "1.0.1" - Added `Configure Microsoft Defender for Azure Cosmos DB to be enabled` to the `Deploy Microsoft Defender for Cloud configuration` initiative and updated version to `3.1.0` - Fixing issue [issue #1081](https://github.com/Azure/Enterprise-Scale/issues/1081) - Added `AZFWFlowTrace` category for Azure Firewall in associated Diagnostic Policy -- Deprecated the following ALZ policies +- Deprecated the following ALZ policies - [Deploy-Nsg-FlowLogs](https://www.azadvertizer.net/azpolicyadvertizer/Deploy-Nsg-FlowLogs.html) - [Deploy-Nsg-FlowLogs-to-LA](https://www.azadvertizer.net/azpolicyadvertizer/Deploy-Nsg-FlowLogs-to-LA.html) - [Deny-PublicIp](https://www.azadvertizer.net/azpolicyadvertizer/Deny-PublicIP.html) @@ -126,7 +162,7 @@ Impacted assignment: Deploy-ASC-Monitoring - "**"Deploy-MDFC-Config"**" definition update - Updated policy definitions set Deploy-MDFC-Config, Deploy-MDFC-Config(US Gov), Deploy-MDFC-Config (China) - added new parameter `minimalSeverity`. - - added default value for multiple parameters. + - added default value for multiple parameters. ### Other @@ -175,13 +211,13 @@ Impacted assignment: Deploy-ASC-Monitoring #### Docs -- Updated the Enterprise-scale [Wiki](https://github.com/Azure/terraform-azurerm-caf-enterprise-scale/wiki/) to reflect the latest updates on Azure landing zone accelerator. - - - [Deploy Azure landing zone portal accelerator](./Deploying-ALZ) - - [Deployment guidance for Small Enterprises](./Deploying-ALZ-BasicSetup) - - [How to deploy without hybrid connectivity](./Deploying-ALZ-Foundation) - - [Deployment with hub and spoke network topology](./Deploying-ALZ-HubAndSpoke) - - [Deployment with Azure VWAN network topology](./Deploying-ALZ-VWAN) +- Updated the Enterprise-scale [Wiki](https://github.com/Azure/terraform-azurerm-caf-enterprise-scale/wiki/) to reflect the latest updates on Azure landing zone accelerator. + + - [Deploy Azure landing zone portal accelerator](./Deploying-ALZ) + - [Deployment guidance for Small Enterprises](./Deploying-ALZ-BasicSetup) + - [How to deploy without hybrid connectivity](./Deploying-ALZ-Foundation) + - [Deployment with hub and spoke network topology](./Deploying-ALZ-HubAndSpoke) + - [Deployment with Azure VWAN network topology](./Deploying-ALZ-VWAN) #### Tooling @@ -251,7 +287,7 @@ Impacted assignment: Deploy-ASC-Monitoring #### Docs -- Updated the [Policies included in Enterprise-Scale Landing Zones](https://github.com/Azure/Enterprise-Scale/blob/main/docs/ESLZ-Policies.md) page. +- Updated the [Policies included in Enterprise-Scale Landing Zones](https://github.com/Azure/Enterprise-Scale/wiki/ALZ-Policies) page. - Updated the ALZ Terraform module [Wiki](https://github.com/Azure/terraform-azurerm-caf-enterprise-scale/wiki/) with new examples and improved coverage of variable configuration. #### Tooling @@ -267,7 +303,7 @@ Impacted assignment: Deploy-ASC-Monitoring - Add 2 new categories for Host Pools Diagnostic Settings - `NetworkData` - `SessionHostManagement` -- Added AVD Scaling Plans Diagnostic Settings called `Deploy-Diagnostics-AVDScalingPlans` for Azure Public only - as not supported in Fairfax or Mooncake as per https://docs.microsoft.com/azure/virtual-desktop/autoscale-scaling-plan - Fixing issue [issue #962](https://github.com/Azure/Enterprise-Scale/issues/962) +- Added AVD Scaling Plans Diagnostic Settings called `Deploy-Diagnostics-AVDScalingPlans` for Azure Public only - as not supported in Fairfax or Mooncake as per - Fixing issue [issue #962](https://github.com/Azure/Enterprise-Scale/issues/962) - Added to `Deploy-Diagnostics-LogAnalytics` Policy Initiative - Added additional log categories to `Deploy-Diagnostics-Firewall` for Azure Firewall Diagnostic Settings Policy - Fixing issue [issue #985](https://github.com/Azure/Enterprise-Scale/issues/985) - Added additional log categories to `Deploy-Diagnostics-APIMgmt` for Azure API Management Diagnostic Settings Policy - Fixing issue [issue #986](https://github.com/Azure/Enterprise-Scale/issues/986) @@ -442,9 +478,8 @@ Impacted assignment: Deploy-ASC-Monitoring #### Docs - - Updates to [User Guide](https://github.com/Azure/Enterprise-Scale/wiki) to include instructions for deploying each of the reference implementations. -- Updated Deploying Enterprise Scale wiki page with updated workflow steps. (https://github.com/Azure/Enterprise-Scale/pull/827) +- Updated Deploying Enterprise Scale wiki page with updated workflow steps. () - Updated [implementation FAQ](https://github.com/Azure/Enterprise-Scale/wiki/FAQ) and moved to the Wiki - Added [architecture FAQ](https://docs.microsoft.com/azure/cloud-adoption-framework/ready/enterprise-scale/faq) to the CAF docs @@ -476,14 +511,14 @@ Impacted assignment: Deploy-ASC-Monitoring #### Docs -- Added reference to Enterprise-Scale Analytics (https://github.com/Azure/Enterprise-Scale/pull/809) -- Added Do-It-Yourself instructions for deploying Enterprise-Scale in Azure China regions (https://github.com/Azure/Enterprise-Scale/pull/802) +- Added reference to Enterprise-Scale Analytics () +- Added Do-It-Yourself instructions for deploying Enterprise-Scale in Azure China regions () #### Tooling -- Added Option to select Azure Firewall SKU (https://github.com/Azure/Enterprise-Scale/pull/793) +- Added Option to select Azure Firewall SKU () - [AzOps release v1.5.0](https://github.com/Azure/AzOps/releases/tag/1.5.0) -- Enabled support for Enterprise-Scale landing zones deployments to Azure gov (https://github.com/Azure/Enterprise-Scale/pull/820) +- Enabled support for Enterprise-Scale landing zones deployments to Azure gov () ### Policy @@ -502,7 +537,7 @@ Impacted assignment: Deploy-ASC-Monitoring #### Docs -- Updated [Enterprise Agreement enrollment and Azure Active Directory tenants](https://docs.microsoft.com/en-us/azure/cloud-adoption-framework/ready/enterprise-scale/enterprise-enrollment-and-azure-ad-tenants) CAF doc +- Updated [Enterprise Agreement enrollment and Azure Active Directory tenants](https://docs.microsoft.com/azure/cloud-adoption-framework/ready/enterprise-scale/enterprise-enrollment-and-azure-ad-tenants) CAF doc - Added CSP, MCA & other billing offers - Added information on how an EA relates to Azure AD and ties in with RBAC - Lots of updates to the [Terraform Module for Cloud Adoption Framework Enterprise-scale wiki](https://github.com/Azure/terraform-azurerm-caf-enterprise-scale/wiki) @@ -514,14 +549,15 @@ Impacted assignment: Deploy-ASC-Monitoring - [Do-It-Yourself deployment instructions for Enterprise-Scale using Azure PowerShell released](https://github.com/Azure/Enterprise-Scale/tree/main/eslzArm) - Update subscription filter in reference implementation UI experience. Subscriptions with state != "Enabled" will be excluded from the list of available subscriptions. - Removed old codebase for the different reference implementations, and converged to a single [ARM codebase](https://github.com/Azure/Enterprise-Scale/tree/main/eslzArm) -- Improved Network CIDR Range Validation within the Azure Portal experience (https://github.com/Azure/Enterprise-Scale/pull/767). +- Improved Network CIDR Range Validation within the Azure Portal experience (). #### Policy -- Some minor changes to parameters and variables, tidying up some code. +- Some minor changes to parameters and variables, tidying up some code. - See [PR #727](https://github.com/Azure/Enterprise-Scale/pull/727) - Updated policy Deploy-VNET-HubSpoke to address [#726](https://github.com/Azure/Enterprise-Scale/issues/726) and [#728](https://github.com/Azure/Enterprise-Scale/issues/728) - See [PR #772](https://github.com/Azure/Enterprise-Scale/pull/772) + #### Other - Published resources from the first Enterprise Scale Community Call - held on the 25th August 2021 @@ -553,7 +589,7 @@ Impacted assignment: Deploy-ASC-Monitoring - The composite ARM templates can be sequenced on their own, independently of each other (although strict sequencing is required to ensure the same outcome) - Guidance coming soon for this - Customers can deploy from private repository if they want to sequence at their own pace. -- ~~[AzOps release v1.3.0](https://github.com/Azure/AzOps/releases/tag/1.3.0)~~ +- ~~[AzOps release v1.3.0](https://github.com/Azure/AzOps/releases/tag/1.3.0)~~ - ~~[AzOps release v1.3.1](https://github.com/Azure/AzOps/releases/tag/1.3.1)~~ - [AzOps release v1.4.0](https://github.com/Azure/AzOps/releases/tag/1.4.0) @@ -561,8 +597,8 @@ Impacted assignment: Deploy-ASC-Monitoring - Various custom ESLZ Azure Policies have moved to Built-In Azure Policies, see below table for more detail: -> You may continue to use the ESLZ custom Azure Policy as it will still function as it does today. However, we recommend you move to assigning the new Built-In version of the Azure Policy. -> +> You may continue to use the ESLZ custom Azure Policy as it will still function as it does today. However, we recommend you move to assigning the new Built-In version of the Azure Policy. +> > **Please note** that moving to the new Built-In Policy Definition will require a new Policy Assignment and removing the previous Policy Assignment, which will mean compliance history for the Policy Assignment will be lost. However, if you have configured your Activity Logs and Security Center to export to a Log Analytics Workspace; Policy Assignment historic data will be stored here as per the retention duration configured. **Policy Definitions Updates** @@ -604,7 +640,7 @@ Impacted assignment: Deploy-ASC-Monitoring | Deny-PublicEndpoints | Public network access should be disabled for PAAS services | Network | Deny-PublicPaaSEndpoints | Public network access should be disabled for PaaS services | N/A | Moved to using Built-In policy definitions only (as above) | | ***New Policy*** | ***New Policy*** | N/A | Deploy-Private-DNS-Zones | Configure Azure PaaS services to use private DNS zones | Network | | -- Moved several of the diagnostics Policies to built-in, and updating the diagnostics Initiative +- Moved several of the diagnostics Policies to built-in, and updating the diagnostics Initiative - This means there's a new resource name as update of existing one is not be allowed due to removal of parameters - Added Policy Initiative for enforcing Private DNS Zone Association with Private Link (using built-in) - Added Policy Initiative for denying Public Endpoints (using built-in) diff --git a/docs/wiki/_Footer.md b/docs/wiki/_Footer.md index d86e0f6a56..0f6cc0ff04 100644 --- a/docs/wiki/_Footer.md +++ b/docs/wiki/_Footer.md @@ -1,4 +1,6 @@ -**This wiki is being actively developed** + +**This wiki is being actively developed** + If you discover any documentation bugs or would like to request new content, please raise them as an [issue](https://github.com/Azure/Enterprise-Scale/issues). -Contributions to this wiki are done through the main repo under [docs/wiki](https://github.com/Azure/Enterprise-Scale/tree/main/docs/wiki). \ No newline at end of file +Contributions to this wiki are done through the main repo under [docs/wiki](https://github.com/Azure/Enterprise-Scale/tree/main/docs/wiki). diff --git a/docs/wiki/_Sidebar.md b/docs/wiki/_Sidebar.md index f460ec354b..55683ad6ea 100644 --- a/docs/wiki/_Sidebar.md +++ b/docs/wiki/_Sidebar.md @@ -1,32 +1,47 @@ # Wiki content -* [What's New?](https://github.com/Azure/Enterprise-Scale/wiki/Whats-new) -* [Community Calls](https://github.com/Azure/Enterprise-Scale/wiki/Community-Calls) -* [Frequently Asked Questions (FAQ)](https://github.com/Azure/Enterprise-Scale/wiki/FAQ) -* [What is Enterprise-Scale](https://github.com/Azure/Enterprise-Scale/wiki/What-is-Enterprise-Scale) - * [What is Enterprise-Scale reference implementation?](https://github.com/Azure/Enterprise-Scale/wiki/What-is-Enterprise-Scale#what-is-enterprise-scale-reference-implementation) - * [Pricing](https://github.com/Azure/Enterprise-Scale/wiki/What-is-Enterprise-Scale#pricing) - * [What if I already have an existing Azure footprint](https://github.com/Azure/Enterprise-Scale/wiki/What-is-Enterprise-Scale#what-if-i-already-have-an-existing-azure-footprint) -* [How Enterprise-Scale Works](https://github.com/Azure/Enterprise-Scale/wiki/How-Enterprise-Scale-Works) - * [Enterprise-Scale design principles](https://github.com/Azure/Enterprise-Scale/wiki/How-Enterprise-Scale-Works#enterprise-scale-design-principles) - * [Separating platform and landing zones](https://github.com/Azure/Enterprise-Scale/wiki/How-Enterprise-Scale-Works#separating-platform-and-landing-zones) - * [Enterprise-Scale Management Group Structure](https://github.com/Azure/Enterprise-Scale/wiki/How-Enterprise-Scale-Works#enterprise-scale-management-group-structure) - * [What happens when you deploy Enterprise-Scale?](https://github.com/Azure/Enterprise-Scale/wiki/How-Enterprise-Scale-Works#what-happens-when-you-deploy-enterprise-scale) -* Deploying Azure landing zone accelerator (Enterprise-Scale) - * [Pre-requisites](https://github.com/Azure/Enterprise-Scale/wiki/Deploying-ALZ-Pre-requisites) - * [Telemetry Tracking Using Customer Usage Attribution (PID)](https://github.com/Azure/Enterprise-Scale/wiki/Deploying-ALZ-CustomerUsage) - * [Deploy without hybrid connectivity to on-premises](https://github.com/Azure/Enterprise-Scale/wiki/Deploying-ALZ-Foundation) - * [Deploy with a hub and spoke based network topology](https://github.com/Azure/Enterprise-Scale/wiki/Deploying-ALZ-HubAndSpoke) - * [Deploy with an Azure Virtual WAN based network topology](https://github.com/Azure/Enterprise-Scale/wiki/Deploying-ALZ-VWAN) - * [Deploy for Small Enterprises](https://github.com/Azure/Enterprise-Scale/wiki/Deploying-ALZ-BasicSetup) - * [Operating the Azure platform using AzOps (Infrastructure as Code with GitHub Actions)](https://github.com/Azure/Enterprise-Scale/wiki/Deploying-Enterprise-Scale-Platform-DevOps#operating-the-azure-platform-using-azops-infrastructure-as-code-with-github-actions) -* [Create subscriptions / landing zones using AzOps](https://github.com/Azure/Enterprise-Scale/wiki/Create-Landingzones) - * [Create landing zones (subscription) using AzOps](https://github.com/Azure/Enterprise-Scale/wiki/Create-Landingzones#create-landing-zones-subscription-using-azops) - * [Pre-requisites](https://github.com/Azure/Enterprise-Scale/wiki/Create-Landingzones.md#pre-requisites) - * [Enable Service Principal to create landing zones](https://github.com/Azure/Enterprise-Scale/wiki/Create-Landingzones#enable-service-principal-to-create-landing-zones) - * [ARM template repository](https://github.com/Azure/Enterprise-Scale/wiki/Create-Landingzones#arm-template-repository) - * [Create a new landing zone (subscriptions)](https://github.com/Azure/Enterprise-Scale/wiki/Create-Landingzones#create-a-new-landing-zone-subscriptions) -* [Azure Landing Zones Deprecated Services](https://github.com/Azure/Enterprise-Scale/wiki/ALZ-Deprecated-Services) +* [What's New?](./Whats-new) +* [Community Calls](./Community-Calls) +* [Frequently Asked Questions (FAQ)](./FAQ) +* [Known issues](./ALZ-Known-Issues) +* [What is Enterprise-Scale](./What-is-Enterprise-Scale) + * [Architecture](./ALZ-Architecture) + * [Policies](./ALZ-Policies) + * [What is the reference implementation?](./What-is-Enterprise-Scale#what-is-enterprise-scale-reference-implementation) + * [Pricing](./What-is-Enterprise-Scale#pricing) + * [What if I already have an existing Azure footprint](./What-is-Enterprise-Scale#what-if-i-already-have-an-existing-azure-footprint) +* [How it Works](./How-Enterprise-Scale-Works) + * [Design principles](./How-Enterprise-Scale-Works#enterprise-scale-design-principles) + * [Separating platform and landing zones](./How-Enterprise-Scale-Works#separating-platform-and-landing-zones) + * [Management Group Structure](./How-Enterprise-Scale-Works#enterprise-scale-management-group-structure) + * [What happens when you deploy Enterprise-Scale?](./How-Enterprise-Scale-Works#what-happens-when-you-deploy-enterprise-scale) +* Deploying Enterprise-Scale + * [Pre-requisites](./Deploying-ALZ-Pre-requisites) + * [Configure AAD permissions](./ALZ-Setup-aad-permissions) + * [Configure Azure permissions](./ALZ-Setup-azure) + * [Deploy landing zones](./ALZ-Deploy-landing-zones) + * [Deploy reference implementations](./ALZ-Deploy-reference-implementations) + * [Telemetry Tracking Using Customer Usage Attribution (PID)](./Deploying-ALZ-CustomerUsage) + * [Deploy without hybrid connectivity to on-premises](./Deploying-ALZ-Foundation) + * [Deploy with a hub and spoke based network topology](./Deploying-ALZ-HubAndSpoke) + * [Deploy with an Azure Virtual WAN based network topology](./Deploying-ALZ-VWAN) + * [Deploy for Small Enterprises](./Deploying-ALZ-BasicSetup) + * [Operating the Azure platform using AzOps (Infrastructure as Code with GitHub Actions)](./Deploying-ALZ-Platform-DevOps#operating-the-azure-platform-using-azops-infrastructure-as-code-with-github-actions) + * [Deploy workloads](./ALZ-Deploy-workloads) +* [Create subscriptions / landing zones using AzOps](./Create-Landingzones) + * [Create landing zones (subscription) using AzOps](./Create-Landingzones#create-landing-zones-subscription-using-azops) + * [Pre-requisites](./Create-Landingzones#pre-requisites) + * [Enable Service Principal to create landing zones](./Create-Landingzones#enable-service-principal-to-create-landing-zones) + * [ARM template repository](./Create-Landingzones#arm-template-repository) + * [Create a new landing zone (subscriptions)](./Create-Landingzones#create-a-new-landing-zone-subscriptions) +* [Azure Landing Zones Deprecated Services](./ALZ-Deprecated-Services) * Azure Landing Zone (ALZ) Policies - * [Policies included in Azure landing zones reference implementations](https://github.com/Azure/Enterprise-Scale/wiki/ALZ-Policies) - * [Migrate Azure landing zones custom policies to Azure built-in policies](https://github.com/Azure/Enterprise-Scale/wiki/migrate-alz-policies-to-builtin) + * [Policies included in Azure landing zones reference implementations](./ALZ-Policies) + * [Migrate Azure landing zones custom policies to Azure built-in policies](./Migrate-ALZ-Policies-to-Built%E2%80%90in) + * [Updating Azure landing zones custom policies to latest](./Update-ALZ-Custom-Policies-to-Latest) +* [Contributing](./ALZ-Contribution-Guide) + * [Reporting Bugs](./ALZ-Contribution-Guide#reporting-bugs) + * [Feature Requests](./ALZ-Contribution-Guide#feature-requests) + * [Report a security vulnerability](./ALZ-Contribution-Guide#report-a-security-vulnerability) + * [How to submit a pull request to upstream repo](./ALZ-Contribution-Guide#how-to-submit-pull-request-to-upstream-repo) + * [ALZ Custom Policies](./ALZ-Contribution-Guide#working-with-alz-custom-policies) diff --git a/docs/wiki/media/1.1.update-alz-custom-policy-def-search.png b/docs/wiki/media/1.1.update-alz-custom-policy-def-search.png new file mode 100644 index 0000000000..722fcafa27 Binary files /dev/null and b/docs/wiki/media/1.1.update-alz-custom-policy-def-search.png differ diff --git a/docs/wiki/media/1.2.update-alz-custom-policy-def-name.png b/docs/wiki/media/1.2.update-alz-custom-policy-def-name.png new file mode 100644 index 0000000000..aa26f451b8 Binary files /dev/null and b/docs/wiki/media/1.2.update-alz-custom-policy-def-name.png differ diff --git a/docs/wiki/media/2.1.update-alz-custom-policy-assignments.png b/docs/wiki/media/2.1.update-alz-custom-policy-assignments.png new file mode 100644 index 0000000000..b0a6758099 Binary files /dev/null and b/docs/wiki/media/2.1.update-alz-custom-policy-assignments.png differ diff --git a/docs/wiki/media/2.2.update-alz-custom-policy-delete-assignments.png b/docs/wiki/media/2.2.update-alz-custom-policy-delete-assignments.png new file mode 100644 index 0000000000..12056133e9 Binary files /dev/null and b/docs/wiki/media/2.2.update-alz-custom-policy-delete-assignments.png differ diff --git a/docs/wiki/media/2.3.update-alz-custom-policy-search.png b/docs/wiki/media/2.3.update-alz-custom-policy-search.png new file mode 100644 index 0000000000..2193a3199e Binary files /dev/null and b/docs/wiki/media/2.3.update-alz-custom-policy-search.png differ diff --git a/docs/wiki/media/2.4.update-alz-custom-policy-search.png b/docs/wiki/media/2.4.update-alz-custom-policy-search.png new file mode 100644 index 0000000000..701177256d Binary files /dev/null and b/docs/wiki/media/2.4.update-alz-custom-policy-search.png differ diff --git a/docs/wiki/media/AzGovViz-ALZ-Policy-outDated.png b/docs/wiki/media/AzGovViz-ALZ-Policy-outDated.png new file mode 100644 index 0000000000..404a4d643b Binary files /dev/null and b/docs/wiki/media/AzGovViz-ALZ-Policy-outDated.png differ diff --git a/docs/media/ES-process.png b/docs/wiki/media/ES-process.png similarity index 100% rename from docs/media/ES-process.png rename to docs/wiki/media/ES-process.png diff --git a/docs/media/ESLZ.gif b/docs/wiki/media/ESLZ.gif similarity index 100% rename from docs/media/ESLZ.gif rename to docs/wiki/media/ESLZ.gif diff --git a/docs/media/Enterprise Scale - PolicyDefinitionAssignments.xlsx b/docs/wiki/media/Enterprise Scale - PolicyDefinitionAssignments.xlsx similarity index 100% rename from docs/media/Enterprise Scale - PolicyDefinitionAssignments.xlsx rename to docs/wiki/media/Enterprise Scale - PolicyDefinitionAssignments.xlsx diff --git a/docs/media/Enterprise-scale architecture.vsdx b/docs/wiki/media/Enterprise-scale architecture.vsdx similarity index 100% rename from docs/media/Enterprise-scale architecture.vsdx rename to docs/wiki/media/Enterprise-scale architecture.vsdx diff --git a/docs/media/HS.png b/docs/wiki/media/HS.png similarity index 100% rename from docs/media/HS.png rename to docs/wiki/media/HS.png diff --git a/docs/media/MvnetHS.png b/docs/wiki/media/MvnetHS.png similarity index 100% rename from docs/media/MvnetHS.png rename to docs/wiki/media/MvnetHS.png diff --git a/docs/media/MvnetHSPP.png b/docs/wiki/media/MvnetHSPP.png similarity index 100% rename from docs/media/MvnetHSPP.png rename to docs/wiki/media/MvnetHSPP.png diff --git a/docs/media/North Star process visuals.pptx b/docs/wiki/media/North Star process visuals.pptx similarity index 100% rename from docs/media/North Star process visuals.pptx rename to docs/wiki/media/North Star process visuals.pptx diff --git a/docs/media/NorthStar Networking images.pptx b/docs/wiki/media/NorthStar Networking images.pptx similarity index 100% rename from docs/media/NorthStar Networking images.pptx rename to docs/wiki/media/NorthStar Networking images.pptx diff --git a/docs/media/aad-rolesandadministrators.png b/docs/wiki/media/aad-rolesandadministrators.png similarity index 100% rename from docs/media/aad-rolesandadministrators.png rename to docs/wiki/media/aad-rolesandadministrators.png diff --git a/docs/media/ado-add-build-policy.png b/docs/wiki/media/ado-add-build-policy.png similarity index 100% rename from docs/media/ado-add-build-policy.png rename to docs/wiki/media/ado-add-build-policy.png diff --git a/docs/media/ado-complete-pr.png b/docs/wiki/media/ado-complete-pr.png similarity index 100% rename from docs/media/ado-complete-pr.png rename to docs/wiki/media/ado-complete-pr.png diff --git a/docs/media/ado-env-approval.png b/docs/wiki/media/ado-env-approval.png similarity index 100% rename from docs/media/ado-env-approval.png rename to docs/wiki/media/ado-env-approval.png diff --git a/docs/media/ado-import-repo.png b/docs/wiki/media/ado-import-repo.png similarity index 100% rename from docs/media/ado-import-repo.png rename to docs/wiki/media/ado-import-repo.png diff --git a/docs/media/ado-manage-repo.png b/docs/wiki/media/ado-manage-repo.png similarity index 100% rename from docs/media/ado-manage-repo.png rename to docs/wiki/media/ado-manage-repo.png diff --git a/docs/media/ado-permissions-group.png b/docs/wiki/media/ado-permissions-group.png similarity index 100% rename from docs/media/ado-permissions-group.png rename to docs/wiki/media/ado-permissions-group.png diff --git a/docs/media/ado-pipeline-create.png b/docs/wiki/media/ado-pipeline-create.png similarity index 100% rename from docs/media/ado-pipeline-create.png rename to docs/wiki/media/ado-pipeline-create.png diff --git a/docs/media/ado-pipeline-variable.png b/docs/wiki/media/ado-pipeline-variable.png similarity index 100% rename from docs/media/ado-pipeline-variable.png rename to docs/wiki/media/ado-pipeline-variable.png diff --git a/docs/media/ado-repo-buildservice.png b/docs/wiki/media/ado-repo-buildservice.png similarity index 100% rename from docs/media/ado-repo-buildservice.png rename to docs/wiki/media/ado-repo-buildservice.png diff --git a/docs/media/ado-repo-forcepush.png b/docs/wiki/media/ado-repo-forcepush.png similarity index 100% rename from docs/media/ado-repo-forcepush.png rename to docs/wiki/media/ado-repo-forcepush.png diff --git a/docs/media/ado-repo-policy.png b/docs/wiki/media/ado-repo-policy.png similarity index 100% rename from docs/media/ado-repo-policy.png rename to docs/wiki/media/ado-repo-policy.png diff --git a/docs/media/cmanged-nt.png b/docs/wiki/media/cmanged-nt.png similarity index 100% rename from docs/media/cmanged-nt.png rename to docs/wiki/media/cmanged-nt.png diff --git a/docs/media/devops.png b/docs/wiki/media/devops.png similarity index 100% rename from docs/media/devops.png rename to docs/wiki/media/devops.png diff --git a/docs/media/directory-reader.png b/docs/wiki/media/directory-reader.png similarity index 100% rename from docs/media/directory-reader.png rename to docs/wiki/media/directory-reader.png diff --git a/docs/media/e2e-armtemplate.png b/docs/wiki/media/e2e-armtemplate.png similarity index 100% rename from docs/media/e2e-armtemplate.png rename to docs/wiki/media/e2e-armtemplate.png diff --git a/docs/media/ea.png b/docs/wiki/media/ea.png similarity index 100% rename from docs/media/ea.png rename to docs/wiki/media/ea.png diff --git a/docs/media/eg-net-top.png b/docs/wiki/media/eg-net-top.png similarity index 100% rename from docs/media/eg-net-top.png rename to docs/wiki/media/eg-net-top.png diff --git a/docs/media/enc-flows.png b/docs/wiki/media/enc-flows.png similarity index 100% rename from docs/media/enc-flows.png rename to docs/wiki/media/enc-flows.png diff --git a/docs/media/es-hubspoke-nw.png b/docs/wiki/media/es-hubspoke-nw.png similarity index 100% rename from docs/media/es-hubspoke-nw.png rename to docs/wiki/media/es-hubspoke-nw.png diff --git a/docs/media/es-iab.png b/docs/wiki/media/es-iab.png similarity index 100% rename from docs/media/es-iab.png rename to docs/wiki/media/es-iab.png diff --git a/docs/wiki/media/example-def-in-init-2.png b/docs/wiki/media/example-def-in-init-2.png new file mode 100644 index 0000000000..495a349569 Binary files /dev/null and b/docs/wiki/media/example-def-in-init-2.png differ diff --git a/docs/wiki/media/example-def-in-init.png b/docs/wiki/media/example-def-in-init.png new file mode 100644 index 0000000000..0f73cfe7c5 Binary files /dev/null and b/docs/wiki/media/example-def-in-init.png differ diff --git a/docs/media/global-transit.png b/docs/wiki/media/global-transit.png similarity index 100% rename from docs/media/global-transit.png rename to docs/wiki/media/global-transit.png diff --git a/docs/media/iam.png b/docs/wiki/media/iam.png similarity index 100% rename from docs/media/iam.png rename to docs/wiki/media/iam.png diff --git a/docs/media/implementation-scope.png b/docs/wiki/media/implementation-scope.png similarity index 100% rename from docs/media/implementation-scope.png rename to docs/wiki/media/implementation-scope.png diff --git a/docs/media/lz-design.png b/docs/wiki/media/lz-design.png similarity index 100% rename from docs/media/lz-design.png rename to docs/wiki/media/lz-design.png diff --git a/docs/media/mg-hierarchy-settings.png b/docs/wiki/media/mg-hierarchy-settings.png similarity index 100% rename from docs/media/mg-hierarchy-settings.png rename to docs/wiki/media/mg-hierarchy-settings.png diff --git a/docs/media/mgmt-mon.png b/docs/wiki/media/mgmt-mon.png similarity index 100% rename from docs/media/mgmt-mon.png rename to docs/wiki/media/mgmt-mon.png diff --git a/docs/media/net-con.png b/docs/wiki/media/net-con.png similarity index 100% rename from docs/media/net-con.png rename to docs/wiki/media/net-con.png diff --git a/docs/media/net-con2.png b/docs/wiki/media/net-con2.png similarity index 100% rename from docs/media/net-con2.png rename to docs/wiki/media/net-con2.png diff --git a/docs/media/ns-arch.png b/docs/wiki/media/ns-arch.png similarity index 100% rename from docs/media/ns-arch.png rename to docs/wiki/media/ns-arch.png diff --git a/docs/wiki/media/policies-bicep-example.png b/docs/wiki/media/policies-bicep-example.png new file mode 100644 index 0000000000..14052a8c1e Binary files /dev/null and b/docs/wiki/media/policies-bicep-example.png differ diff --git a/docs/wiki/media/policy-metadata-example.png b/docs/wiki/media/policy-metadata-example.png new file mode 100644 index 0000000000..25b55429dc Binary files /dev/null and b/docs/wiki/media/policy-metadata-example.png differ diff --git a/docs/wiki/media/pr-example.png b/docs/wiki/media/pr-example.png new file mode 100644 index 0000000000..476ecc8b23 Binary files /dev/null and b/docs/wiki/media/pr-example.png differ diff --git a/docs/media/sub-org.png b/docs/wiki/media/sub-org.png similarity index 100% rename from docs/media/sub-org.png rename to docs/wiki/media/sub-org.png diff --git a/eslzArm/eslz-portal.json b/eslzArm/eslz-portal.json index 33eb6b9443..eec04b9d2e 100644 --- a/eslzArm/eslz-portal.json +++ b/eslzArm/eslz-portal.json @@ -405,26 +405,6 @@ }, "visible": "[equals(steps('management').enableLogAnalytics,'Yes')]" }, - { - "name": "enableActivityLog", - "type": "Microsoft.Common.OptionsGroup", - "label": "Deploy Activity Log solution", - "defaultValue": "Yes (recommended)", - "toolTip": "If 'Yes' is selected when also adding a subscription for management, ARM will deploy resources and enable them for continuous compliance", - "constraints": { - "allowedValues": [ - { - "label": "Yes (recommended)", - "value": "Yes" - }, - { - "label": "No", - "value": "No" - } - ] - }, - "visible": "[equals(steps('management').enableLogAnalytics,'Yes')]" - }, { "name": "enableVmInsights", "type": "Microsoft.Common.OptionsGroup", @@ -2646,7 +2626,6 @@ "enableAgentHealth": "[steps('management').enableAgentHealth]", "enableChangeTracking": "[steps('management').enableChangeTracking]", "enableUpdateMgmt": "[steps('management').enableUpdateMgmt]", - "enableActivityLog": "[steps('management').enableActivityLog]", "enableVmInsights": "[steps('management').enableVmInsights]", "enableServiceMap": "[steps('management').enableServiceMap]", "enableSqlAssessment": "[steps('management').enableSqlAssessment]", @@ -2730,4 +2709,4 @@ "location": "[steps('basics').resourceScope.location.name]" } } -} +} \ No newline at end of file diff --git a/eslzArm/eslzArm.json b/eslzArm/eslzArm.json index b871351ba7..2e7b20292c 100644 --- a/eslzArm/eslzArm.json +++ b/eslzArm/eslzArm.json @@ -72,14 +72,6 @@ ], "defaultValue": "Yes" }, - "enableActivityLog": { - "type": "string", - "allowedValues": [ - "Yes", - "No" - ], - "defaultValue": "Yes" - }, "enableVmInsights": { "type": "string", "allowedValues": [ @@ -702,6 +694,7 @@ "deploymentUris": { "managementGroups": "[uri(deployment().properties.templateLink.uri, 'managementGroupTemplates/mgmtGroupStructure/mgmtGroups.json')]", "managementGroupsLite": "[uri(deployment().properties.templateLink.uri, 'managementGroupTemplates/mgmtGroupStructure/mgmtGroupsLite.json')]", + "roleDefinitions": "[uri(deployment().properties.templateLink.uri, 'managementGroupTemplates/roleDefinitions/customRoleDefinitions.json')]", "policyDefinitions": "[uri(deployment().properties.templateLink.uri, 'managementGroupTemplates/policyDefinitions/policies.json')]", "vnetConnectivityHub": "[uri(deployment().properties.templateLink.uri, 'subscriptionTemplates/hubspoke-connectivity.json')]", "vwanConnectivityHub": "[uri(deployment().properties.templateLink.uri, 'subscriptionTemplates/vwan-connectivity.json')]", @@ -756,6 +749,7 @@ "corpPeeringDeploymentName": "[take(concat('alz-CorpPeering', variables('deploymentSuffix')), 60)]", "connectivitySubscriptionPlacement": "[take(concat('alz-ConnectivitySub', variables('deploymentSuffix')), 64)]", "identitySubscriptionPlacement": "[take(concat('alz-IdentitySub', variables('deploymentSuffix')), 64)]", + "roleDefsDeploymentName": "[take(concat('alz-RoleDefs', variables('deploymentSuffix')), 64)]", "policyDeploymentName": "[take(concat('alz-Policy', variables('deploymentSuffix')), 64)]", "azOpsRbacDeploymentName": "[take(concat('alz-AzOpsRbac', variables('deploymentSuffix')), 64)]", "azOpsRgDeploymentName": "[take(concat('alz-AzOpsRg', variables('deploymentSuffix')), 64)]", @@ -1041,6 +1035,25 @@ } } }, + { + // Deploying ALZ Custom RBAC Role Definitions + "type": "Microsoft.Resources/deployments", + "apiVersion": "2019-10-01", + "name": "[variables('deploymentNames').roleDefsDeploymentName]", + "location": "[deployment().location]", + "scope": "[concat('Microsoft.Management/managementGroups/', parameters('enterpriseScaleCompanyPrefix'))]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/deployments', variables('deploymentNames').mgmtGroupDeploymentName)]", + "[resourceId('Microsoft.Resources/deployments', variables('esLiteDeploymentNames').mgmtGroupLiteDeploymentName)]" + ], + "properties": { + "mode": "Incremental", + "templateLink": { + "contentVersion": "1.0.0.0", + "uri": "[variables('deploymentUris').roleDefinitions]" + } + } + }, /* The following deployments will deploy the required proactive and preventive Azure policies for ESLZ policy driven governance */ @@ -1224,7 +1237,7 @@ }, { // Deploying Log Analytics solutions to Log Analytics workspace if condition is true - "condition": "[and(and(not(empty(parameters('managementSubscriptionId'))), equals(parameters('enableLogAnalytics'), 'Yes')), equals(parameters('enableLogAnalytics'), 'Yes'), or(or(or(or(or(or(or(equals(parameters('enableSecuritySolution'), 'Yes'), equals(parameters('enableAgentHealth'), 'Yes')), equals(parameters('enableChangeTracking'), 'Yes')), equals(parameters('enableUpdateMgmt'), 'Yes'), equals(parameters('enableActivityLog'), 'Yes')), equals(parameters('enableVmInsights'), 'Yes')), equals(parameters('enableServiceMap'), 'Yes'), equals(parameters('enableSqlAssessment'), 'Yes')), equals(parameters('enableSqlAdvancedThreatProtection'), 'Yes')), equals(parameters('enableSqlVulnerabilityAssessment'), 'Yes')))]", + "condition": "[and(and(not(empty(parameters('managementSubscriptionId'))), equals(parameters('enableLogAnalytics'), 'Yes')), equals(parameters('enableLogAnalytics'), 'Yes'), or(or(or(or(or(or(equals(parameters('enableSecuritySolution'), 'Yes'), equals(parameters('enableAgentHealth'), 'Yes')), equals(parameters('enableChangeTracking'), 'Yes')), equals(parameters('enableUpdateMgmt'), 'Yes'), equals(parameters('enableVmInsights'), 'Yes')), equals(parameters('enableServiceMap'), 'Yes'), equals(parameters('enableSqlAssessment'), 'Yes')), equals(parameters('enableSqlAdvancedThreatProtection'), 'Yes')), equals(parameters('enableSqlVulnerabilityAssessment'), 'Yes')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2020-10-01", "name": "[variables('deploymentNames').monitoringSolutionsDeploymentName]", @@ -1262,9 +1275,6 @@ "enableUpdateMgmt": { "value": "[parameters('enableUpdateMgmt')]" }, - "enableActivityLog": { - "value": "[parameters('enableActivityLog')]" - }, "enableVmInsights": { "value": "[parameters('enableVmInsights')]" }, @@ -3140,7 +3150,7 @@ */ { // Deploying Log Analytics solutions to Log Analytics workspace if condition is true - "condition": "[and(and(not(empty(parameters('singlePlatformSubscriptionId'))), equals(parameters('enableLogAnalytics'), 'Yes')), equals(parameters('enableLogAnalytics'), 'Yes'), or(or(or(or(or(or(or(equals(parameters('enableSecuritySolution'), 'Yes'), equals(parameters('enableAgentHealth'), 'Yes')), equals(parameters('enableChangeTracking'), 'Yes')), equals(parameters('enableUpdateMgmt'), 'Yes'), equals(parameters('enableActivityLog'), 'Yes')), equals(parameters('enableVmInsights'), 'Yes')), equals(parameters('enableServiceMap'), 'Yes'), equals(parameters('enableSqlAssessment'), 'Yes')), equals(parameters('enableSqlAdvancedThreatProtection'), 'Yes')), equals(parameters('enableSqlVulnerabilityAssessment'), 'Yes')))]", + "condition": "[and(and(not(empty(parameters('singlePlatformSubscriptionId'))), equals(parameters('enableLogAnalytics'), 'Yes')), equals(parameters('enableLogAnalytics'), 'Yes'), or(or(or(or(or(or(equals(parameters('enableSecuritySolution'), 'Yes'), equals(parameters('enableAgentHealth'), 'Yes')), equals(parameters('enableChangeTracking'), 'Yes')), equals(parameters('enableUpdateMgmt'), 'Yes'), equals(parameters('enableVmInsights'), 'Yes')), equals(parameters('enableServiceMap'), 'Yes'), equals(parameters('enableSqlAssessment'), 'Yes')), equals(parameters('enableSqlAdvancedThreatProtection'), 'Yes')), equals(parameters('enableSqlVulnerabilityAssessment'), 'Yes')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2020-10-01", "name": "[variables('esLiteDeploymentNames').monitoringSolutionsLiteDeploymentName]", @@ -3178,9 +3188,6 @@ "enableUpdateMgmt": { "value": "[parameters('enableUpdateMgmt')]" }, - "enableActivityLog": { - "value": "[parameters('enableActivityLog')]" - }, "enableVmInsights": { "value": "[parameters('enableVmInsights')]" }, diff --git a/eslzArm/eslzArm.test.param.json b/eslzArm/eslzArm.test.param.json index 193c7aa3eb..8b0f4eff2e 100644 --- a/eslzArm/eslzArm.test.param.json +++ b/eslzArm/eslzArm.test.param.json @@ -23,9 +23,6 @@ "enableUpdateMgmt": { "value": "Yes" }, - "enableActivityLog": { - "value": "Yes" - }, "enableVmInsights": { "value": "Yes" }, @@ -243,4 +240,4 @@ "value": 30 } } -} +} \ No newline at end of file diff --git a/eslzArm/fairfaxeslz-portal.json b/eslzArm/fairfaxeslz-portal.json index d10becae6b..32b146ccdf 100644 --- a/eslzArm/fairfaxeslz-portal.json +++ b/eslzArm/fairfaxeslz-portal.json @@ -269,26 +269,6 @@ }, "visible": "[equals(steps('esGoalState').esLogAnalytics,'Yes')]" }, - { - "name": "esActivityLog", - "type": "Microsoft.Common.OptionsGroup", - "label": "Deploy Activity Log solution", - "defaultValue": "Yes (recommended)", - "toolTip": "If 'Yes' is selected when also adding a subscription for management, ARM will deploy resources and enable them for continous compliance", - "constraints": { - "allowedValues": [ - { - "label": "Yes (recommended)", - "value": "Yes" - }, - { - "label": "No", - "value": "No" - } - ] - }, - "visible": "[equals(steps('esGoalState').esLogAnalytics,'Yes')]" - }, { "name": "esVmInsights", "type": "Microsoft.Common.OptionsGroup", @@ -2357,7 +2337,6 @@ "enableAgentHealth": "[steps('esGoalState').esAgentSolution]", "enableChangeTracking": "[steps('esGoalState').esChangeTracking]", "enableUpdateMgmt": "[steps('esGoalState').esUpdateMgmt]", - "enableActivityLog": "[steps('esGoalState').esActivityLog]", "enableVmInsights": "[steps('esGoalState').esVmInsights]", "enableServiceMap": "[steps('esGoalState').esServiceMap]", "enableSqlAssessment": "[steps('esGoalState').esSqlAssessment]", diff --git a/eslzArm/managementGroupTemplates/policyDefinitions/policies.json b/eslzArm/managementGroupTemplates/policyDefinitions/policies.json index 04f51f5f59..dcc5802efb 100644 --- a/eslzArm/managementGroupTemplates/policyDefinitions/policies.json +++ b/eslzArm/managementGroupTemplates/policyDefinitions/policies.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.13.1.58284", - "templateHash": "10588324334232217896" + "templateHash": "2880619846496960745" } }, "parameters": { @@ -40,7 +40,7 @@ "$fxv#100": "{\n \"name\": \"Deny-MachineLearning-ComputeCluster-RemoteLoginPortPublicAccess\",\n \"type\": \"Microsoft.Authorization/policyDefinitions\",\n \"apiVersion\": \"2021-06-01\",\n \"scope\": null,\n \"properties\": {\n \"policyType\": \"Custom\",\n \"mode\": \"All\",\n \"displayName\": \"Deny public access of Azure Machine Learning clusters via SSH\",\n \"description\": \"Deny public access of Azure Machine Learning clusters via SSH.\",\n \"metadata\": {\n \"version\": \"1.1.0\",\n \"category\": \"Machine Learning\",\n \"source\": \"https://github.com/Azure/Enterprise-Scale/\",\n \"alzCloudEnvironments\": [\n \"AzureCloud\"\n ]\n },\n \"parameters\": {\n \"effect\": {\n \"type\": \"String\",\n \"metadata\": {\n \"displayName\": \"Effect\",\n \"description\": \"Enable or disable the execution of the policy\"\n },\n \"allowedValues\": [\n \"Audit\",\n \"Disabled\",\n \"Deny\"\n ],\n \"defaultValue\": \"Deny\"\n }\n },\n \"policyRule\": {\n \"if\": {\n \"allOf\": [\n {\n \"field\": \"type\",\n \"equals\": \"Microsoft.MachineLearningServices/workspaces/computes\"\n },\n {\n \"field\": \"Microsoft.MachineLearningServices/workspaces/computes/computeType\",\n \"equals\": \"AmlCompute\"\n },\n {\n \"anyOf\": [\n {\n \"field\": \"Microsoft.MachineLearningServices/workspaces/computes/remoteLoginPortPublicAccess\",\n \"exists\": false\n },\n {\n \"field\": \"Microsoft.MachineLearningServices/workspaces/computes/remoteLoginPortPublicAccess\",\n \"notEquals\": \"Disabled\"\n }\n ]\n }\n ]\n },\n \"then\": {\n \"effect\": \"[[parameters('effect')]\"\n }\n }\n }\n}\n", "$fxv#101": "{\n \"name\": \"Deny-MachineLearning-ComputeCluster-Scale\",\n \"type\": \"Microsoft.Authorization/policyDefinitions\",\n \"apiVersion\": \"2021-06-01\",\n \"scope\": null,\n \"properties\": {\n \"policyType\": \"Custom\",\n \"mode\": \"Indexed\",\n \"displayName\": \"Enforce scale settings for Azure Machine Learning compute clusters\",\n \"description\": \"Enforce scale settings for Azure Machine Learning compute clusters.\",\n \"metadata\": {\n \"version\": \"1.0.0\",\n \"category\": \"Budget\",\n \"source\": \"https://github.com/Azure/Enterprise-Scale/\",\n \"alzCloudEnvironments\": [\n \"AzureCloud\"\n ]\n },\n \"parameters\": {\n \"effect\": {\n \"type\": \"String\",\n \"metadata\": {\n \"displayName\": \"Effect\",\n \"description\": \"Enable or disable the execution of the policy\"\n },\n \"allowedValues\": [\n \"Audit\",\n \"Disabled\",\n \"Deny\"\n ],\n \"defaultValue\": \"Deny\"\n },\n \"maxNodeCount\": {\n \"type\": \"Integer\",\n \"metadata\": {\n \"displayName\": \"Maximum Node Count\",\n \"description\": \"Specifies the maximum node count of AML Clusters\"\n },\n \"defaultValue\": 10\n },\n \"minNodeCount\": {\n \"type\": \"Integer\",\n \"metadata\": {\n \"displayName\": \"Minimum Node Count\",\n \"description\": \"Specifies the minimum node count of AML Clusters\"\n },\n \"defaultValue\": 0\n },\n \"maxNodeIdleTimeInSecondsBeforeScaleDown\": {\n \"type\": \"Integer\",\n \"metadata\": {\n \"displayName\": \"Maximum Node Idle Time in Seconds Before Scaledown\",\n \"description\": \"Specifies the maximum node idle time in seconds before scaledown\"\n },\n \"defaultValue\": 900\n }\n },\n \"policyRule\": {\n \"if\": {\n \"allOf\": [\n {\n \"field\": \"type\",\n \"equals\": \"Microsoft.MachineLearningServices/workspaces/computes\"\n },\n {\n \"field\": \"Microsoft.MachineLearningServices/workspaces/computes/computeType\",\n \"equals\": \"AmlCompute\"\n },\n {\n \"anyOf\": [\n {\n \"field\": \"Microsoft.MachineLearningServices/workspaces/computes/scaleSettings.maxNodeCount\",\n \"greater\": \"[[parameters('maxNodeCount')]\"\n },\n {\n \"field\": \"Microsoft.MachineLearningServices/workspaces/computes/scaleSettings.minNodeCount\",\n \"greater\": \"[[parameters('minNodeCount')]\"\n },\n {\n \"value\": \"[[int(last(split(replace(replace(replace(replace(replace(replace(replace(field('Microsoft.MachineLearningServices/workspaces/computes/scaleSettings.nodeIdleTimeBeforeScaleDown'), 'P', '/'), 'Y', '/'), 'M', '/'), 'D', '/'), 'T', '/'), 'H', '/'), 'S', ''), '/')))]\",\n \"greater\": \"[[parameters('maxNodeIdleTimeInSecondsBeforeScaleDown')]\"\n }\n ]\n }\n ]\n },\n \"then\": {\n \"effect\": \"[[parameters('effect')]\"\n }\n }\n }\n}\n", "$fxv#102": "{\n \"name\": \"Deny-MachineLearning-HbiWorkspace\",\n \"type\": \"Microsoft.Authorization/policyDefinitions\",\n \"apiVersion\": \"2021-06-01\",\n \"scope\": null,\n \"properties\": {\n \"policyType\": \"Custom\",\n \"mode\": \"Indexed\",\n \"displayName\": \"Enforces high business impact Azure Machine Learning Workspaces\",\n \"description\": \"Enforces high business impact Azure Machine Learning workspaces.\",\n \"metadata\": {\n \"version\": \"1.0.0\",\n \"category\": \"Machine Learning\",\n \"source\": \"https://github.com/Azure/Enterprise-Scale/\",\n \"alzCloudEnvironments\": [\n \"AzureCloud\"\n ]\n },\n \"parameters\": {\n \"effect\": {\n \"type\": \"String\",\n \"metadata\": {\n \"displayName\": \"Effect\",\n \"description\": \"Enable or disable the execution of the policy\"\n },\n \"allowedValues\": [\n \"Audit\",\n \"Disabled\",\n \"Deny\"\n ],\n \"defaultValue\": \"Deny\"\n }\n },\n \"policyRule\": {\n \"if\": {\n \"allOf\": [\n {\n \"field\": \"type\",\n \"equals\": \"Microsoft.MachineLearningServices/workspaces\"\n },\n {\n \"anyOf\": [\n {\n \"field\": \"Microsoft.MachineLearningServices/workspaces/hbiWorkspace\",\n \"exists\": false\n },\n {\n \"field\": \"Microsoft.MachineLearningServices/workspaces/hbiWorkspace\",\n \"notEquals\": true\n }\n ]\n }\n ]\n },\n \"then\": {\n \"effect\": \"[[parameters('effect')]\"\n }\n }\n }\n}\n", - "$fxv#103": "{\n \"name\": \"Deny-MachineLearning-PublicAccessWhenBehindVnet\",\n \"type\": \"Microsoft.Authorization/policyDefinitions\",\n \"apiVersion\": \"2021-06-01\",\n \"scope\": null,\n \"properties\": {\n \"policyType\": \"Custom\",\n \"mode\": \"Indexed\",\n \"displayName\": \"Deny public acces behind vnet to Azure Machine Learning workspace\",\n \"description\": \"Deny public access behind vnet to Azure Machine Learning workspaces.\",\n \"metadata\": {\n \"version\": \"1.0.0\",\n \"category\": \"Machine Learning\",\n \"source\": \"https://github.com/Azure/Enterprise-Scale/\",\n \"alzCloudEnvironments\": [\n \"AzureCloud\"\n ]\n },\n \"parameters\": {\n \"effect\": {\n \"type\": \"String\",\n \"metadata\": {\n \"displayName\": \"Effect\",\n \"description\": \"Enable or disable the execution of the policy\"\n },\n \"allowedValues\": [\n \"Audit\",\n \"Disabled\",\n \"Deny\"\n ],\n \"defaultValue\": \"Deny\"\n }\n },\n \"policyRule\": {\n \"if\": {\n \"allOf\": [\n {\n \"field\": \"type\",\n \"equals\": \"Microsoft.MachineLearningServices/workspaces\"\n },\n {\n \"anyOf\": [\n {\n \"field\": \"Microsoft.MachineLearningServices/workspaces/allowPublicAccessWhenBehindVnet\",\n \"exists\": false\n },\n {\n \"field\": \"Microsoft.MachineLearningServices/workspaces/allowPublicAccessWhenBehindVnet\",\n \"notEquals\": false\n }\n ]\n }\n ]\n },\n \"then\": {\n \"effect\": \"[[parameters('effect')]\"\n }\n }\n }\n}\n", + "$fxv#103": "{\n \"name\": \"Deny-MachineLearning-PublicAccessWhenBehindVnet\",\n \"type\": \"Microsoft.Authorization/policyDefinitions\",\n \"apiVersion\": \"2021-06-01\",\n \"scope\": null,\n \"properties\": {\n \"policyType\": \"Custom\",\n \"mode\": \"Indexed\",\n \"displayName\": \"Deny public access behind vnet to Azure Machine Learning workspace\",\n \"description\": \"Deny public access behind vnet to Azure Machine Learning workspaces.\",\n \"metadata\": {\n \"version\": \"1.0.1\",\n \"category\": \"Machine Learning\",\n \"source\": \"https://github.com/Azure/Enterprise-Scale/\",\n \"alzCloudEnvironments\": [\n \"AzureCloud\"\n ]\n },\n \"parameters\": {\n \"effect\": {\n \"type\": \"String\",\n \"metadata\": {\n \"displayName\": \"Effect\",\n \"description\": \"Enable or disable the execution of the policy\"\n },\n \"allowedValues\": [\n \"Audit\",\n \"Disabled\",\n \"Deny\"\n ],\n \"defaultValue\": \"Deny\"\n }\n },\n \"policyRule\": {\n \"if\": {\n \"allOf\": [\n {\n \"field\": \"type\",\n \"equals\": \"Microsoft.MachineLearningServices/workspaces\"\n },\n {\n \"anyOf\": [\n {\n \"field\": \"Microsoft.MachineLearningServices/workspaces/allowPublicAccessWhenBehindVnet\",\n \"exists\": false\n },\n {\n \"field\": \"Microsoft.MachineLearningServices/workspaces/allowPublicAccessWhenBehindVnet\",\n \"notEquals\": false\n }\n ]\n }\n ]\n },\n \"then\": {\n \"effect\": \"[[parameters('effect')]\"\n }\n }\n }\n}\n", "$fxv#104": "{\n \"name\": \"Deny-MachineLearning-PublicNetworkAccess\",\n \"type\": \"Microsoft.Authorization/policyDefinitions\",\n \"apiVersion\": \"2021-06-01\",\n \"scope\": null,\n \"properties\": {\n \"policyType\": \"Custom\",\n \"mode\": \"Indexed\",\n \"displayName\": \"Azure Machine Learning should have disabled public network access\",\n \"description\": \"Denies public network access for Azure Machine Learning workspaces.\",\n \"metadata\": {\n \"version\": \"1.0.0\",\n \"category\": \"Machine Learning\",\n \"source\": \"https://github.com/Azure/Enterprise-Scale/\",\n \"alzCloudEnvironments\": [\n \"AzureCloud\"\n ]\n },\n \"parameters\": {\n \"effect\": {\n \"type\": \"String\",\n \"metadata\": {\n \"displayName\": \"Effect\",\n \"description\": \"Enable or disable the execution of the policy\"\n },\n \"allowedValues\": [\n \"Audit\",\n \"Disabled\",\n \"Deny\"\n ],\n \"defaultValue\": \"Deny\"\n }\n },\n \"policyRule\": {\n \"if\": {\n \"allOf\": [\n {\n \"field\": \"type\",\n \"equals\": \"Microsoft.MachineLearningServices/workspaces\"\n },\n {\n \"field\": \"Microsoft.MachineLearningServices/workspaces/publicNetworkAccess\",\n \"notEquals\": \"Disabled\"\n }\n ]\n },\n \"then\": {\n \"effect\": \"[[parameters('effect')]\"\n }\n }\n }\n}\n", "$fxv#105": "{\n \"name\": \"Deploy-Budget\",\n \"type\": \"Microsoft.Authorization/policyDefinitions\",\n \"apiVersion\": \"2021-06-01\",\n \"scope\": null,\n \"properties\": {\n \"policyType\": \"Custom\",\n \"mode\": \"All\",\n \"displayName\": \"Deploy a default budget on all subscriptions under the assigned scope\",\n \"description\": \"Deploy a default budget on all subscriptions under the assigned scope\",\n \"metadata\": {\n \"version\": \"1.1.0\",\n \"category\": \"Budget\",\n \"source\": \"https://github.com/Azure/Enterprise-Scale/\",\n \"alzCloudEnvironments\": [\n \"AzureCloud\",\n \"AzureUSGovernment\"\n ]\n },\n \"parameters\": {\n \"effect\": {\n \"type\": \"String\",\n \"defaultValue\": \"DeployIfNotExists\",\n \"allowedValues\": [\n \"DeployIfNotExists\",\n \"AuditIfNotExists\",\n \"Disabled\"\n ],\n \"metadata\": {\n \"description\": \"Enable or disable the execution of the policy\"\n }\n },\n \"budgetName\": {\n \"type\": \"String\",\n \"defaultValue\": \"budget-set-by-policy\",\n \"metadata\": {\n \"description\": \"The name for the budget to be created\"\n }\n },\n \"amount\": {\n \"type\": \"String\",\n \"defaultValue\": \"1000\",\n \"metadata\": {\n \"description\": \"The total amount of cost or usage to track with the budget\"\n }\n },\n \"timeGrain\": {\n \"type\": \"String\",\n \"defaultValue\": \"Monthly\",\n \"allowedValues\": [\n \"Monthly\",\n \"Quarterly\",\n \"Annually\",\n \"BillingMonth\",\n \"BillingQuarter\",\n \"BillingAnnual\"\n ],\n \"metadata\": {\n \"description\": \"The time covered by a budget. Tracking of the amount will be reset based on the time grain.\"\n }\n },\n \"firstThreshold\": {\n \"type\": \"String\",\n \"defaultValue\": \"90\",\n \"metadata\": {\n \"description\": \"Threshold value associated with a notification. Notification is sent when the cost exceeded the threshold. It is always percent and has to be between 0 and 1000.\"\n }\n },\n \"secondThreshold\": {\n \"type\": \"String\",\n \"defaultValue\": \"100\",\n \"metadata\": {\n \"description\": \"Threshold value associated with a notification. Notification is sent when the cost exceeded the threshold. It is always percent and has to be between 0 and 1000.\"\n }\n },\n \"contactRoles\": {\n \"type\": \"Array\",\n \"defaultValue\": [\n \"Owner\",\n \"Contributor\"\n ],\n \"metadata\": {\n \"description\": \"The list of contact RBAC roles, in an array, to send the budget notification to when the threshold is exceeded.\"\n }\n },\n \"contactEmails\": {\n \"type\": \"Array\",\n \"defaultValue\": [],\n \"metadata\": {\n \"description\": \"The list of email addresses, in an array, to send the budget notification to when the threshold is exceeded.\"\n }\n },\n \"contactGroups\": {\n \"type\": \"Array\",\n \"defaultValue\": [],\n \"metadata\": {\n \"description\": \"The list of action groups, in an array, to send the budget notification to when the threshold is exceeded. It accepts array of strings.\"\n }\n }\n },\n \"policyRule\": {\n \"if\": {\n \"allOf\": [\n {\n \"field\": \"type\",\n \"equals\": \"Microsoft.Resources/subscriptions\"\n }\n ]\n },\n \"then\": {\n \"effect\": \"[[parameters('effect')]\",\n \"details\": {\n \"type\": \"Microsoft.Consumption/budgets\",\n \"deploymentScope\": \"subscription\",\n \"existenceScope\": \"subscription\",\n \"existenceCondition\": {\n \"allOf\": [\n {\n \"field\": \"Microsoft.Consumption/budgets/amount\",\n \"equals\": \"[[parameters('amount')]\"\n },\n {\n \"field\": \"Microsoft.Consumption/budgets/timeGrain\",\n \"equals\": \"[[parameters('timeGrain')]\"\n },\n {\n \"field\": \"Microsoft.Consumption/budgets/category\",\n \"equals\": \"Cost\"\n }\n ]\n },\n \"roleDefinitionIds\": [\n \"/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c\"\n ],\n \"deployment\": {\n \"location\": \"northeurope\",\n \"properties\": {\n \"mode\": \"Incremental\",\n \"parameters\": {\n \"budgetName\": {\n \"value\": \"[[parameters('budgetName')]\"\n },\n \"amount\": {\n \"value\": \"[[parameters('amount')]\"\n },\n \"timeGrain\": {\n \"value\": \"[[parameters('timeGrain')]\"\n },\n \"firstThreshold\": {\n \"value\": \"[[parameters('firstThreshold')]\"\n },\n \"secondThreshold\": {\n \"value\": \"[[parameters('secondThreshold')]\"\n },\n \"contactEmails\": {\n \"value\": \"[[parameters('contactEmails')]\"\n },\n \"contactRoles\": {\n \"value\": \"[[parameters('contactRoles')]\"\n },\n \"contactGroups\": {\n \"value\": \"[[parameters('contactGroups')]\"\n }\n },\n \"template\": {\n \"$schema\": \"http://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json\",\n \"contentVersion\": \"1.0.0.0\",\n \"parameters\": {\n \"budgetName\": {\n \"type\": \"String\"\n },\n \"amount\": {\n \"type\": \"String\"\n },\n \"timeGrain\": {\n \"type\": \"String\"\n },\n \"firstThreshold\": {\n \"type\": \"String\"\n },\n \"secondThreshold\": {\n \"type\": \"String\"\n },\n \"contactEmails\": {\n \"type\": \"Array\"\n },\n \"contactRoles\": {\n \"type\": \"Array\"\n },\n \"contactGroups\": {\n \"type\": \"Array\"\n },\n \"startDate\": {\n \"type\": \"String\",\n \"defaultValue\": \"[[concat(utcNow('MM'), '/01/', utcNow('yyyy'))]\"\n }\n },\n \"resources\": [\n {\n \"type\": \"Microsoft.Consumption/budgets\",\n \"apiVersion\": \"2019-10-01\",\n \"name\": \"[[parameters('budgetName')]\",\n \"properties\": {\n \"timePeriod\": {\n \"startDate\": \"[[parameters('startDate')]\"\n },\n \"timeGrain\": \"[[parameters('timeGrain')]\",\n \"amount\": \"[[parameters('amount')]\",\n \"category\": \"Cost\",\n \"notifications\": {\n \"NotificationForExceededBudget1\": {\n \"enabled\": true,\n \"operator\": \"GreaterThan\",\n \"threshold\": \"[[parameters('firstThreshold')]\",\n \"contactEmails\": \"[[parameters('contactEmails')]\",\n \"contactRoles\": \"[[parameters('contactRoles')]\",\n \"contactGroups\": \"[[parameters('contactGroups')]\"\n },\n \"NotificationForExceededBudget2\": {\n \"enabled\": true,\n \"operator\": \"GreaterThan\",\n \"threshold\": \"[[parameters('secondThreshold')]\",\n \"contactEmails\": \"[[parameters('contactEmails')]\",\n \"contactRoles\": \"[[parameters('contactRoles')]\",\n \"contactGroups\": \"[[parameters('contactGroups')]\"\n }\n }\n }\n }\n ]\n }\n }\n }\n }\n }\n }\n }\n}\n", "$fxv#106": "{\n \"name\": \"Deploy-Diagnostics-AVDScalingPlans\",\n \"type\": \"Microsoft.Authorization/policyDefinitions\",\n \"apiVersion\": \"2021-06-01\",\n \"scope\": null,\n \"properties\": {\n \"policyType\": \"Custom\",\n \"mode\": \"Indexed\",\n \"displayName\": \"Deploy Diagnostic Settings for AVD Scaling Plans to Log Analytics workspace\",\n \"description\": \"Deploys the diagnostic settings for AVD Scaling Plans to stream to a Log Analytics workspace when any Scaling Plan which is missing this diagnostic settings is created or updated. The Policy will set the diagnostic with all and categorys enabled.\",\n \"metadata\": {\n \"version\": \"1.1.0\",\n \"category\": \"Monitoring\",\n \"source\": \"https://github.com/Azure/Enterprise-Scale/\",\n \"alzCloudEnvironments\": [\n \"AzureCloud\"\n ]\n },\n \"parameters\": {\n \"logAnalytics\": {\n \"type\": \"String\",\n \"metadata\": {\n \"displayName\": \"Log Analytics workspace\",\n \"description\": \"Select Log Analytics workspace from dropdown list. If this workspace is outside of the scope of the assignment you must manually grant 'Log Analytics Contributor' permissions (or similar) to the policy assignment's principal ID.\",\n \"strongType\": \"omsWorkspace\"\n }\n },\n \"effect\": {\n \"type\": \"String\",\n \"defaultValue\": \"DeployIfNotExists\",\n \"allowedValues\": [\n \"DeployIfNotExists\",\n \"Disabled\"\n ],\n \"metadata\": {\n \"displayName\": \"Effect\",\n \"description\": \"Enable or disable the execution of the policy\"\n }\n },\n \"profileName\": {\n \"type\": \"String\",\n \"defaultValue\": \"setbypolicy\",\n \"metadata\": {\n \"displayName\": \"Profile name\",\n \"description\": \"The diagnostic settings profile name\"\n }\n },\n \"logsEnabled\": {\n \"type\": \"String\",\n \"defaultValue\": \"True\",\n \"allowedValues\": [\n \"True\",\n \"False\"\n ],\n \"metadata\": {\n \"displayName\": \"Enable logs\",\n \"description\": \"Whether to enable logs stream to the Log Analytics workspace - True or False\"\n }\n }\n },\n \"policyRule\": {\n \"if\": {\n \"field\": \"type\",\n \"equals\": \"Microsoft.DesktopVirtualization/scalingplans\"\n },\n \"then\": {\n \"effect\": \"[[parameters('effect')]\",\n \"details\": {\n \"type\": \"Microsoft.Insights/diagnosticSettings\",\n \"name\": \"[[parameters('profileName')]\",\n \"existenceCondition\": {\n \"allOf\": [\n {\n \"field\": \"Microsoft.Insights/diagnosticSettings/logs.enabled\",\n \"equals\": \"true\"\n },\n {\n \"field\": \"Microsoft.Insights/diagnosticSettings/workspaceId\",\n \"equals\": \"[[parameters('logAnalytics')]\"\n }\n ]\n },\n \"roleDefinitionIds\": [\n \"/providers/microsoft.authorization/roleDefinitions/749f88d5-cbae-40b8-bcfc-e573ddc772fa\",\n \"/providers/microsoft.authorization/roleDefinitions/92aaf0da-9dab-42b6-94a3-d43ce8d16293\"\n ],\n \"deployment\": {\n \"properties\": {\n \"mode\": \"Incremental\",\n \"template\": {\n \"$schema\": \"http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#\",\n \"contentVersion\": \"1.0.0.0\",\n \"parameters\": {\n \"resourceName\": {\n \"type\": \"String\"\n },\n \"logAnalytics\": {\n \"type\": \"String\"\n },\n \"location\": {\n \"type\": \"String\"\n },\n \"profileName\": {\n \"type\": \"String\"\n },\n \"logsEnabled\": {\n \"type\": \"String\"\n }\n },\n \"variables\": {},\n \"resources\": [\n {\n \"type\": \"Microsoft.DesktopVirtualization/scalingplans/providers/diagnosticSettings\",\n \"apiVersion\": \"2017-05-01-preview\",\n \"name\": \"[[concat(parameters('resourceName'), '/', 'Microsoft.Insights/', parameters('profileName'))]\",\n \"location\": \"[[parameters('location')]\",\n \"dependsOn\": [],\n \"properties\": {\n \"workspaceId\": \"[[parameters('logAnalytics')]\",\n \"logs\": [\n {\n \"category\": \"Autoscale\",\n \"enabled\": \"[[parameters('logsEnabled')]\"\n }\n ]\n }\n }\n ],\n \"outputs\": {}\n },\n \"parameters\": {\n \"logAnalytics\": {\n \"value\": \"[[parameters('logAnalytics')]\"\n },\n \"location\": {\n \"value\": \"[[field('location')]\"\n },\n \"resourceName\": {\n \"value\": \"[[field('name')]\"\n },\n \"profileName\": {\n \"value\": \"[[parameters('profileName')]\"\n },\n \"logsEnabled\": {\n \"value\": \"[[parameters('logsEnabled')]\"\n }\n }\n }\n }\n }\n }\n }\n }\n}", @@ -87,7 +87,7 @@ "$fxv#21": "{\n \"name\": \"Deny-VNET-Peer-Cross-Sub\",\n \"type\": \"Microsoft.Authorization/policyDefinitions\",\n \"apiVersion\": \"2021-06-01\",\n \"scope\": null,\n \"properties\": {\n \"policyType\": \"Custom\",\n \"mode\": \"All\",\n \"displayName\": \"Deny vNet peering cross subscription.\",\n \"description\": \"This policy denies the creation of vNet Peerings outside of the same subscriptions under the assigned scope.\",\n \"metadata\": {\n \"version\": \"1.0.1\",\n \"category\": \"Network\",\n \"source\": \"https://github.com/Azure/Enterprise-Scale/\",\n \"alzCloudEnvironments\": [\n \"AzureCloud\",\n \"AzureChinaCloud\",\n \"AzureUSGovernment\"\n ]\n },\n \"parameters\": {\n \"effect\": {\n \"type\": \"String\",\n \"metadata\": {\n \"displayName\": \"Effect\",\n \"description\": \"Enable or disable the execution of the policy\"\n },\n \"allowedValues\": [\n \"Audit\",\n \"Deny\",\n \"Disabled\"\n ],\n \"defaultValue\": \"Deny\"\n }\n },\n \"policyRule\": {\n \"if\": {\n \"allOf\": [\n {\n \"field\": \"type\",\n \"equals\": \"Microsoft.Network/virtualNetworks/virtualNetworkPeerings\"\n },\n {\n \"field\": \"Microsoft.Network/virtualNetworks/virtualNetworkPeerings/remoteVirtualNetwork.id\",\n \"notcontains\": \"[[subscription().id]\"\n }\n ]\n },\n \"then\": {\n \"effect\": \"[[parameters('effect')]\"\n }\n }\n }\n}\n", "$fxv#22": "{\n \"name\": \"Deny-VNET-Peering-To-Non-Approved-VNETs\",\n \"type\": \"Microsoft.Authorization/policyDefinitions\",\n \"apiVersion\": \"2021-06-01\",\n \"scope\": null,\n \"properties\": {\n \"policyType\": \"Custom\",\n \"mode\": \"All\",\n \"displayName\": \"Deny vNet peering to non-approved vNets\",\n \"description\": \"This policy denies the creation of vNet Peerings to non-approved vNets under the assigned scope.\",\n \"metadata\": {\n \"version\": \"1.0.0\",\n \"category\": \"Network\",\n \"source\": \"https://github.com/Azure/Enterprise-Scale/\",\n \"alzCloudEnvironments\": [\n \"AzureCloud\",\n \"AzureChinaCloud\",\n \"AzureUSGovernment\"\n ]\n },\n \"parameters\": {\n \"effect\": {\n \"type\": \"String\",\n \"metadata\": {\n \"displayName\": \"Effect\",\n \"description\": \"Enable or disable the execution of the policy\"\n },\n \"allowedValues\": [\n \"Audit\",\n \"Deny\",\n \"Disabled\"\n ],\n \"defaultValue\": \"Deny\"\n },\n \"allowedVnets\": {\n \"type\": \"Array\",\n \"metadata\": {\n \"displayName\": \"Allowed vNets to peer with\",\n \"description\": \"Array of allowed vNets that can be peered with. Must be entered using their resource ID. Example: /subscriptions/{subId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworks/{vnetName}\"\n },\n \"defaultValue\": []\n }\n },\n \"policyRule\": {\n \"if\": {\n \"anyOf\": [\n {\n \"allOf\": [\n {\n \"field\": \"type\",\n \"equals\": \"Microsoft.Network/virtualNetworks/virtualNetworkPeerings\"\n },\n {\n \"not\": {\n \"field\": \"Microsoft.Network/virtualNetworks/virtualNetworkPeerings/remoteVirtualNetwork.id\",\n \"in\": \"[[parameters('allowedVnets')]\"\n }\n }\n ]\n },\n {\n \"allOf\": [\n {\n \"field\": \"type\",\n \"equals\": \"Microsoft.Network/virtualNetworks\"\n },\n {\n \"not\": {\n \"field\": \"Microsoft.Network/virtualNetworks/virtualNetworkPeerings[*].remoteVirtualNetwork.id\",\n \"in\": \"[[parameters('allowedVnets')]\"\n }\n },\n {\n \"not\": {\n \"field\": \"Microsoft.Network/virtualNetworks/virtualNetworkPeerings[*].remoteVirtualNetwork.id\",\n \"exists\": false\n }\n }\n ]\n }\n ]\n },\n \"then\": {\n \"effect\": \"[[parameters('effect')]\"\n }\n }\n }\n}\n", "$fxv#23": "{\n \"name\": \"Deny-VNet-Peering\",\n \"type\": \"Microsoft.Authorization/policyDefinitions\",\n \"apiVersion\": \"2021-06-01\",\n \"scope\": null,\n \"properties\": {\n \"policyType\": \"Custom\",\n \"mode\": \"All\",\n \"displayName\": \"Deny vNet peering \",\n \"description\": \"This policy denies the creation of vNet Peerings under the assigned scope.\",\n \"metadata\": {\n \"version\": \"1.0.1\",\n \"category\": \"Network\",\n \"source\": \"https://github.com/Azure/Enterprise-Scale/\",\n \"alzCloudEnvironments\": [\n \"AzureCloud\",\n \"AzureChinaCloud\",\n \"AzureUSGovernment\"\n ]\n },\n \"parameters\": {\n \"effect\": {\n \"type\": \"String\",\n \"allowedValues\": [\n \"Audit\",\n \"Deny\",\n \"Disabled\"\n ],\n \"defaultValue\": \"Deny\",\n \"metadata\": {\n \"displayName\": \"Effect\",\n \"description\": \"Enable or disable the execution of the policy\"\n }\n }\n },\n \"policyRule\": {\n \"if\": {\n \"field\": \"type\",\n \"equals\": \"Microsoft.Network/virtualNetworks/virtualNetworkPeerings\"\n },\n \"then\": {\n \"effect\": \"[[parameters('effect')]\"\n }\n }\n }\n}\n", - "$fxv#24": "{\n \"name\": \"Deploy-ASC-SecurityContacts\",\n \"type\": \"Microsoft.Authorization/policyDefinitions\",\n \"apiVersion\": \"2021-06-01\",\n \"scope\": null,\n \"properties\": {\n \"policyType\": \"Custom\",\n \"mode\": \"All\",\n \"displayName\": \"Deploy Microsoft Defender for Cloud Security Contacts\",\n \"description\": \"Deploy Microsoft Defender for Cloud Security Contacts\",\n \"metadata\": {\n \"version\": \"1.0.0\",\n \"category\": \"Security Center\",\n \"source\": \"https://github.com/Azure/Enterprise-Scale/\",\n \"alzCloudEnvironments\": [\n \"AzureCloud\",\n \"AzureChinaCloud\",\n \"AzureUSGovernment\"\n ]\n },\n \"parameters\": {\n \"emailSecurityContact\": {\n \"type\": \"string\",\n \"metadata\": {\n \"displayName\": \"Security contacts email address\",\n \"description\": \"Provide email address for Azure Security Center contact details\"\n }\n },\n \"effect\": {\n \"type\": \"string\",\n \"defaultValue\": \"DeployIfNotExists\",\n \"allowedValues\": [\n \"DeployIfNotExists\",\n \"Disabled\"\n ],\n \"metadata\": {\n \"displayName\": \"Effect\",\n \"description\": \"Enable or disable the execution of the policy\"\n }\n },\n \"minimalSeverity\": {\n \"type\": \"string\",\n \"defaultValue\": \"High\",\n \"allowedValues\": [\n \"High\",\n \"Medium\",\n \"Low\"\n ],\n \"metadata\": {\n \"displayName\": \"Minimal severity\",\n \"description\": \"Defines the minimal alert severity which will be sent as email notifications\"\n }\n }\n },\n \"policyRule\": {\n \"if\": {\n \"allOf\": [\n {\n \"field\": \"type\",\n \"equals\": \"Microsoft.Resources/subscriptions\"\n }\n ]\n },\n \"then\": {\n \"effect\": \"[[parameters('effect')]\",\n \"details\": {\n \"type\": \"Microsoft.Security/securityContacts\",\n \"deploymentScope\": \"subscription\",\n \"existenceScope\": \"subscription\",\n \"roleDefinitionIds\": [\n \"/providers/Microsoft.Authorization/roleDefinitions/fb1c8493-542b-48eb-b624-b4c8fea62acd\"\n ],\n \"existenceCondition\": {\n \"allOf\": [\n {\n \"field\": \"Microsoft.Security/securityContacts/email\",\n \"contains\": \"[[parameters('emailSecurityContact')]\"\n },\n {\n \"field\": \"Microsoft.Security/securityContacts/alertNotifications.minimalSeverity\",\n \"contains\": \"[[parameters('minimalSeverity')]\"\n },\n {\n \"field\": \"type\",\n \"equals\": \"Microsoft.Security/securityContacts\"\n },\n {\n \"field\": \"Microsoft.Security/securityContacts/alertNotifications\",\n \"equals\": \"On\"\n },\n {\n \"field\": \"Microsoft.Security/securityContacts/alertsToAdmins\",\n \"equals\": \"On\"\n }\n ]\n },\n \"deployment\": {\n \"location\": \"northeurope\",\n \"properties\": {\n \"mode\": \"incremental\",\n \"parameters\": {\n \"emailSecurityContact\": {\n \"value\": \"[[parameters('emailSecurityContact')]\"\n }\n },\n \"template\": {\n \"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#\",\n \"contentVersion\": \"1.0.0.0\",\n \"parameters\": {\n \"emailSecurityContact\": {\n \"type\": \"string\",\n \"metadata\": {\n \"description\": \"Security contacts email address\"\n }\n }\n },\n \"variables\": {},\n \"resources\": [\n {\n \"type\": \"Microsoft.Security/securityContacts\",\n \"name\": \"default\",\n \"apiVersion\": \"2020-01-01-preview\",\n \"properties\": {\n \"emails\": \"[[parameters('emailSecurityContact')]\",\n \"notificationsByRole\": {\n \"state\": \"On\",\n \"roles\": [\n \"Owner\"\n ]\n },\n \"alertNotifications\": {\n \"state\": \"On\",\n \"minimalSeverity\": \"[[parameters('minimalSeverity')]\"\n }\n }\n }\n ],\n \"outputs\": {}\n }\n }\n }\n }\n }\n }\n }\n}\n", + "$fxv#24": "{\n \"name\": \"Deploy-ASC-SecurityContacts\",\n \"type\": \"Microsoft.Authorization/policyDefinitions\",\n \"apiVersion\": \"2021-06-01\",\n \"scope\": null,\n \"properties\": {\n \"policyType\": \"Custom\",\n \"mode\": \"All\",\n \"displayName\": \"Deploy Microsoft Defender for Cloud Security Contacts\",\n \"description\": \"Deploy Microsoft Defender for Cloud Security Contacts\",\n \"metadata\": {\n \"version\": \"1.1.0\",\n \"category\": \"Security Center\",\n \"source\": \"https://github.com/Azure/Enterprise-Scale/\",\n \"alzCloudEnvironments\": [\n \"AzureCloud\",\n \"AzureChinaCloud\",\n \"AzureUSGovernment\"\n ]\n },\n \"parameters\": {\n \"emailSecurityContact\": {\n \"type\": \"string\",\n \"metadata\": {\n \"displayName\": \"Security contacts email address\",\n \"description\": \"Provide email address for Azure Security Center contact details\"\n }\n },\n \"effect\": {\n \"type\": \"string\",\n \"defaultValue\": \"DeployIfNotExists\",\n \"allowedValues\": [\n \"DeployIfNotExists\",\n \"Disabled\"\n ],\n \"metadata\": {\n \"displayName\": \"Effect\",\n \"description\": \"Enable or disable the execution of the policy\"\n }\n },\n \"minimalSeverity\": {\n \"type\": \"string\",\n \"defaultValue\": \"High\",\n \"allowedValues\": [\n \"High\",\n \"Medium\",\n \"Low\"\n ],\n \"metadata\": {\n \"displayName\": \"Minimal severity\",\n \"description\": \"Defines the minimal alert severity which will be sent as email notifications\"\n }\n }\n },\n \"policyRule\": {\n \"if\": {\n \"allOf\": [\n {\n \"field\": \"type\",\n \"equals\": \"Microsoft.Resources/subscriptions\"\n }\n ]\n },\n \"then\": {\n \"effect\": \"[[parameters('effect')]\",\n \"details\": {\n \"type\": \"Microsoft.Security/securityContacts\",\n \"deploymentScope\": \"subscription\",\n \"existenceScope\": \"subscription\",\n \"roleDefinitionIds\": [\n \"/providers/Microsoft.Authorization/roleDefinitions/fb1c8493-542b-48eb-b624-b4c8fea62acd\"\n ],\n \"existenceCondition\": {\n \"allOf\": [\n {\n \"field\": \"Microsoft.Security/securityContacts/email\",\n \"contains\": \"[[parameters('emailSecurityContact')]\"\n },\n {\n \"field\": \"Microsoft.Security/securityContacts/alertNotifications.minimalSeverity\",\n \"contains\": \"[[parameters('minimalSeverity')]\"\n },\n {\n \"field\": \"type\",\n \"equals\": \"Microsoft.Security/securityContacts\"\n },\n {\n \"field\": \"Microsoft.Security/securityContacts/alertNotifications\",\n \"equals\": \"On\"\n },\n {\n \"field\": \"Microsoft.Security/securityContacts/alertsToAdmins\",\n \"equals\": \"On\"\n }\n ]\n },\n \"deployment\": {\n \"location\": \"northeurope\",\n \"properties\": {\n \"mode\": \"incremental\",\n \"parameters\": {\n \"emailSecurityContact\": {\n \"value\": \"[[parameters('emailSecurityContact')]\"\n },\n \"minimalSeverity\": {\n \"value\": \"[[parameters('minimalSeverity')]\"\n }\n },\n \"template\": {\n \"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#\",\n \"contentVersion\": \"1.0.0.0\",\n \"parameters\": {\n \"emailSecurityContact\": {\n \"type\": \"string\",\n \"metadata\": {\n \"description\": \"Security contacts email address\"\n }\n },\n \"minimalSeverity\": {\n \"type\": \"string\",\n \"metadata\": {\n \"description\": \"Minimal severity level reported\"\n }\n }\n },\n \"variables\": {},\n \"resources\": [\n {\n \"type\": \"Microsoft.Security/securityContacts\",\n \"name\": \"default\",\n \"apiVersion\": \"2020-01-01-preview\",\n \"properties\": {\n \"emails\": \"[[parameters('emailSecurityContact')]\",\n \"notificationsByRole\": {\n \"state\": \"On\",\n \"roles\": [\n \"Owner\"\n ]\n },\n \"alertNotifications\": {\n \"state\": \"On\",\n \"minimalSeverity\": \"[[parameters('minimalSeverity')]\"\n }\n }\n }\n ],\n \"outputs\": {}\n }\n }\n }\n }\n }\n }\n }\n}\n", "$fxv#25": "{\n \"name\": \"Deploy-Custom-Route-Table\",\n \"type\": \"Microsoft.Authorization/policyDefinitions\",\n \"apiVersion\": \"2021-06-01\",\n \"scope\": null,\n \"properties\": {\n \"policyType\": \"Custom\",\n \"mode\": \"Indexed\",\n \"displayName\": \"Deploy a route table with specific user defined routes\",\n \"description\": \"Deploys a route table with specific user defined routes when one does not exist. The route table deployed by the policy must be manually associated to subnet(s)\",\n \"metadata\": {\n \"version\": \"1.0.0\",\n \"category\": \"Network\",\n \"source\": \"https://github.com/Azure/Enterprise-Scale/\",\n \"alzCloudEnvironments\": [\n \"AzureCloud\",\n \"AzureChinaCloud\",\n \"AzureUSGovernment\"\n ]\n },\n \"parameters\": {\n \"effect\": {\n \"type\": \"String\",\n \"metadata\": {\n \"displayName\": \"Effect\",\n \"description\": \"Enable or disable the execution of the policy\"\n },\n \"allowedValues\": [\n \"DeployIfNotExists\",\n \"Disabled\"\n ],\n \"defaultValue\": \"DeployIfNotExists\"\n },\n \"requiredRoutes\": {\n \"type\": \"Array\",\n \"metadata\": {\n \"displayName\": \"requiredRoutes\",\n \"description\": \"Routes that must exist in compliant route tables deployed by this policy\"\n }\n },\n \"vnetRegion\": {\n \"type\": \"String\",\n \"metadata\": {\n \"displayName\": \"vnetRegion\",\n \"description\": \"Only VNets in this region will be evaluated against this policy\"\n }\n },\n \"routeTableName\": {\n \"type\": \"String\",\n \"metadata\": {\n \"displayName\": \"routeTableName\",\n \"description\": \"Name of the route table automatically deployed by this policy\"\n }\n },\n \"disableBgpPropagation\": {\n \"type\": \"Boolean\",\n \"metadata\": {\n \"displayName\": \"DisableBgpPropagation\",\n \"description\": \"Disable BGP Propagation\"\n },\n \"defaultValue\": false\n }\n },\n \"policyRule\": {\n \"if\": {\n \"allOf\": [\n {\n \"field\": \"type\",\n \"equals\": \"Microsoft.Network/virtualNetworks\"\n },\n {\n \"field\": \"location\",\n \"equals\": \"[[parameters('vnetRegion')]\"\n }\n ]\n },\n \"then\": {\n \"effect\": \"[[parameters('effect')]\",\n \"details\": {\n \"type\": \"Microsoft.Network/routeTables\",\n \"existenceCondition\": {\n \"allOf\": [\n {\n \"field\": \"name\",\n \"equals\": \"[[parameters('routeTableName')]\"\n },\n {\n \"count\": {\n \"field\": \"Microsoft.Network/routeTables/routes[*]\",\n \"where\": {\n \"value\": \"[[concat(current('Microsoft.Network/routeTables/routes[*].addressPrefix'), ';', current('Microsoft.Network/routeTables/routes[*].nextHopType'), if(equals(toLower(current('Microsoft.Network/routeTables/routes[*].nextHopType')),'virtualappliance'), concat(';', current('Microsoft.Network/routeTables/routes[*].nextHopIpAddress')), ''))]\",\n \"in\": \"[[parameters('requiredRoutes')]\"\n }\n },\n \"equals\": \"[[length(parameters('requiredRoutes'))]\"\n }\n ]\n },\n \"roleDefinitionIds\": [\n \"/subscriptions/e867a45d-e513-44ac-931e-4741cef80b24/providers/Microsoft.Authorization/roleDefinitions/4d97b98b-1d4f-4787-a291-c67834d212e7\"\n ],\n \"deployment\": {\n \"properties\": {\n \"mode\": \"incremental\",\n \"template\": {\n \"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#\",\n \"contentVersion\": \"1.0.0.0\",\n \"parameters\": {\n \"routeTableName\": {\n \"type\": \"string\"\n },\n \"vnetRegion\": {\n \"type\": \"string\"\n },\n \"requiredRoutes\": {\n \"type\": \"array\"\n },\n \"disableBgpPropagation\": {\n \"type\": \"bool\"\n }\n },\n \"variables\": {\n \"copyLoop\": [\n {\n \"name\": \"routes\",\n \"count\": \"[[[length(parameters('requiredRoutes'))]\",\n \"input\": {\n \"name\": \"[[[concat('route-',copyIndex('routes'))]\",\n \"properties\": {\n \"addressPrefix\": \"[[[split(parameters('requiredRoutes')[copyIndex('routes')], ';')[0]]\",\n \"nextHopType\": \"[[[split(parameters('requiredRoutes')[copyIndex('routes')], ';')[1]]\",\n \"nextHopIpAddress\": \"[[[if(equals(toLower(split(parameters('requiredRoutes')[copyIndex('routes')], ';')[1]),'virtualappliance'),split(parameters('requiredRoutes')[copyIndex('routes')], ';')[2], null())]\"\n }\n }\n }\n ]\n },\n \"resources\": [\n {\n \"type\": \"Microsoft.Resources/deployments\",\n \"apiVersion\": \"2021-04-01\",\n \"name\": \"routeTableDepl\",\n \"properties\": {\n \"mode\": \"Incremental\",\n \"template\": {\n \"$schema\": \"https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#\",\n \"contentVersion\": \"1.0.0.0\",\n \"parameters\": {\n \"routeTableName\": {\n \"type\": \"string\"\n },\n \"vnetRegion\": {\n \"type\": \"string\"\n },\n \"requiredRoutes\": {\n \"type\": \"array\"\n },\n \"disableBgpPropagation\": {\n \"type\": \"bool\"\n }\n },\n \"resources\": [\n {\n \"type\": \"Microsoft.Network/routeTables\",\n \"apiVersion\": \"2021-02-01\",\n \"name\": \"[[[parameters('routeTableName')]\",\n \"location\": \"[[[parameters('vnetRegion')]\",\n \"properties\": {\n \"disableBgpRoutePropagation\": \"[[[parameters('disableBgpPropagation')]\",\n \"copy\": \"[[variables('copyLoop')]\"\n }\n }\n ]\n },\n \"parameters\": {\n \"routeTableName\": {\n \"value\": \"[[parameters('routeTableName')]\"\n },\n \"vnetRegion\": {\n \"value\": \"[[parameters('vnetRegion')]\"\n },\n \"requiredRoutes\": {\n \"value\": \"[[parameters('requiredRoutes')]\"\n },\n \"disableBgpPropagation\": {\n \"value\": \"[[parameters('disableBgpPropagation')]\"\n }\n }\n }\n }\n ]\n },\n \"parameters\": {\n \"routeTableName\": {\n \"value\": \"[[parameters('routeTableName')]\"\n },\n \"vnetRegion\": {\n \"value\": \"[[parameters('vnetRegion')]\"\n },\n \"requiredRoutes\": {\n \"value\": \"[[parameters('requiredRoutes')]\"\n },\n \"disableBgpPropagation\": {\n \"value\": \"[[parameters('disableBgpPropagation')]\"\n }\n }\n }\n }\n }\n }\n }\n }\n}\n", "$fxv#26": "{\n \"name\": \"Deploy-DDoSProtection\",\n \"type\": \"Microsoft.Authorization/policyDefinitions\",\n \"apiVersion\": \"2021-06-01\",\n \"scope\": null,\n \"properties\": {\n \"policyType\": \"Custom\",\n \"mode\": \"All\",\n \"displayName\": \"Deploy an Azure DDoS Network Protection\",\n \"description\": \"Deploys an Azure DDoS Network Protection\",\n \"metadata\": {\n \"version\": \"1.0.1\",\n \"category\": \"Network\",\n \"source\": \"https://github.com/Azure/Enterprise-Scale/\",\n \"alzCloudEnvironments\": [\n \"AzureCloud\",\n \"AzureChinaCloud\",\n \"AzureUSGovernment\"\n ]\n },\n \"parameters\": {\n \"ddosName\": {\n \"type\": \"String\",\n \"metadata\": {\n \"displayName\": \"ddosName\",\n \"description\": \"DDoSVnet\"\n }\n },\n \"ddosRegion\": {\n \"type\": \"String\",\n \"metadata\": {\n \"displayName\": \"ddosRegion\",\n \"description\": \"DDoSVnet location\",\n \"strongType\": \"location\"\n }\n },\n \"rgName\": {\n \"type\": \"String\",\n \"metadata\": {\n \"displayName\": \"rgName\",\n \"description\": \"Provide name for resource group.\"\n }\n },\n \"effect\": {\n \"type\": \"String\",\n \"defaultValue\": \"DeployIfNotExists\",\n \"allowedValues\": [\n \"DeployIfNotExists\",\n \"Disabled\"\n ],\n \"metadata\": {\n \"displayName\": \"Effect\",\n \"description\": \"Enable or disable the execution of the policy\"\n }\n }\n },\n \"policyRule\": {\n \"if\": {\n \"allOf\": [\n {\n \"field\": \"type\",\n \"equals\": \"Microsoft.Resources/subscriptions\"\n }\n ]\n },\n \"then\": {\n \"effect\": \"[[parameters('effect')]\",\n \"details\": {\n \"type\": \"Microsoft.Network/ddosProtectionPlans\",\n \"deploymentScope\": \"subscription\",\n \"existenceScope\": \"resourceGroup\",\n \"resourceGroupName\": \"[[parameters('rgName')]\",\n \"name\": \"[[parameters('ddosName')]\",\n \"roleDefinitionIds\": [\n \"/providers/Microsoft.Authorization/roleDefinitions/4d97b98b-1d4f-4787-a291-c67834d212e7\"\n ],\n \"deployment\": {\n \"location\": \"northeurope\",\n \"properties\": {\n \"mode\": \"Incremental\",\n \"parameters\": {\n \"rgName\": {\n \"value\": \"[[parameters('rgName')]\"\n },\n \"ddosname\": {\n \"value\": \"[[parameters('ddosname')]\"\n },\n \"ddosregion\": {\n \"value\": \"[[parameters('ddosRegion')]\"\n }\n },\n \"template\": {\n \"$schema\": \"http://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json\",\n \"contentVersion\": \"1.0.0.0\",\n \"parameters\": {\n \"rgName\": {\n \"type\": \"String\"\n },\n \"ddosname\": {\n \"type\": \"String\"\n },\n \"ddosRegion\": {\n \"type\": \"String\"\n }\n },\n \"resources\": [\n {\n \"type\": \"Microsoft.Resources/resourceGroups\",\n \"apiVersion\": \"2018-05-01\",\n \"name\": \"[[parameters('rgName')]\",\n \"location\": \"[[deployment().location]\",\n \"properties\": {}\n },\n {\n \"type\": \"Microsoft.Resources/deployments\",\n \"apiVersion\": \"2018-05-01\",\n \"name\": \"ddosprotection\",\n \"resourceGroup\": \"[[parameters('rgName')]\",\n \"dependsOn\": [\n \"[[resourceId('Microsoft.Resources/resourceGroups/', parameters('rgName'))]\"\n ],\n \"properties\": {\n \"mode\": \"Incremental\",\n \"template\": {\n \"$schema\": \"http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json\",\n \"contentVersion\": \"1.0.0.0\",\n \"parameters\": {},\n \"resources\": [\n {\n \"type\": \"Microsoft.Network/ddosProtectionPlans\",\n \"apiVersion\": \"2019-12-01\",\n \"name\": \"[[parameters('ddosName')]\",\n \"location\": \"[[parameters('ddosRegion')]\",\n \"properties\": {}\n }\n ],\n \"outputs\": {}\n }\n }\n }\n ],\n \"outputs\": {}\n }\n }\n }\n }\n }\n }\n }\n}\n", "$fxv#27": "{\n \"name\": \"Deploy-Diagnostics-AA\",\n \"type\": \"Microsoft.Authorization/policyDefinitions\",\n \"apiVersion\": \"2021-06-01\",\n \"scope\": null,\n \"properties\": {\n \"policyType\": \"Custom\",\n \"mode\": \"Indexed\",\n \"displayName\": \"Deploy Diagnostic Settings for Automation to Log Analytics workspace\",\n \"description\": \"Deploys the diagnostic settings for Automation to stream to a Log Analytics workspace when any Automation which is missing this diagnostic settings is created or updated. The Policy will set the diagnostic with all metrics and category enabled\",\n \"metadata\": {\n \"version\": \"1.1.0\",\n \"category\": \"Monitoring\",\n \"source\": \"https://github.com/Azure/Enterprise-Scale/\",\n \"alzCloudEnvironments\": [\n \"AzureCloud\",\n \"AzureChinaCloud\",\n \"AzureUSGovernment\"\n ]\n },\n \"parameters\": {\n \"logAnalytics\": {\n \"type\": \"String\",\n \"metadata\": {\n \"displayName\": \"Log Analytics workspace\",\n \"description\": \"Select Log Analytics workspace from dropdown list. If this workspace is outside of the scope of the assignment you must manually grant 'Log Analytics Contributor' permissions (or similar) to the policy assignment's principal ID.\",\n \"strongType\": \"omsWorkspace\"\n }\n },\n \"effect\": {\n \"type\": \"String\",\n \"defaultValue\": \"DeployIfNotExists\",\n \"allowedValues\": [\n \"DeployIfNotExists\",\n \"Disabled\"\n ],\n \"metadata\": {\n \"displayName\": \"Effect\",\n \"description\": \"Enable or disable the execution of the policy\"\n }\n },\n \"profileName\": {\n \"type\": \"String\",\n \"defaultValue\": \"setbypolicy\",\n \"metadata\": {\n \"displayName\": \"Profile name\",\n \"description\": \"The diagnostic settings profile name\"\n }\n },\n \"metricsEnabled\": {\n \"type\": \"String\",\n \"defaultValue\": \"True\",\n \"allowedValues\": [\n \"True\",\n \"False\"\n ],\n \"metadata\": {\n \"displayName\": \"Enable metrics\",\n \"description\": \"Whether to enable metrics stream to the Log Analytics workspace - True or False\"\n }\n },\n \"logsEnabled\": {\n \"type\": \"String\",\n \"defaultValue\": \"True\",\n \"allowedValues\": [\n \"True\",\n \"False\"\n ],\n \"metadata\": {\n \"displayName\": \"Enable logs\",\n \"description\": \"Whether to enable logs stream to the Log Analytics workspace - True or False\"\n }\n }\n },\n \"policyRule\": {\n \"if\": {\n \"field\": \"type\",\n \"equals\": \"Microsoft.Automation/automationAccounts\"\n },\n \"then\": {\n \"effect\": \"[[parameters('effect')]\",\n \"details\": {\n \"type\": \"Microsoft.Insights/diagnosticSettings\",\n \"name\": \"[[parameters('profileName')]\",\n \"existenceCondition\": {\n \"allOf\": [\n {\n \"field\": \"Microsoft.Insights/diagnosticSettings/logs.enabled\",\n \"equals\": \"true\"\n },\n {\n \"field\": \"Microsoft.Insights/diagnosticSettings/metrics.enabled\",\n \"equals\": \"true\"\n },\n {\n \"field\": \"Microsoft.Insights/diagnosticSettings/workspaceId\",\n \"equals\": \"[[parameters('logAnalytics')]\"\n }\n ]\n },\n \"roleDefinitionIds\": [\n \"/providers/microsoft.authorization/roleDefinitions/749f88d5-cbae-40b8-bcfc-e573ddc772fa\",\n \"/providers/microsoft.authorization/roleDefinitions/92aaf0da-9dab-42b6-94a3-d43ce8d16293\"\n ],\n \"deployment\": {\n \"properties\": {\n \"mode\": \"Incremental\",\n \"template\": {\n \"$schema\": \"http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#\",\n \"contentVersion\": \"1.0.0.0\",\n \"parameters\": {\n \"resourceName\": {\n \"type\": \"String\"\n },\n \"logAnalytics\": {\n \"type\": \"String\"\n },\n \"location\": {\n \"type\": \"String\"\n },\n \"profileName\": {\n \"type\": \"String\"\n },\n \"metricsEnabled\": {\n \"type\": \"String\"\n },\n \"logsEnabled\": {\n \"type\": \"String\"\n }\n },\n \"variables\": {},\n \"resources\": [\n {\n \"type\": \"Microsoft.Automation/automationAccounts/providers/diagnosticSettings\",\n \"apiVersion\": \"2017-05-01-preview\",\n \"name\": \"[[concat(parameters('resourceName'), '/', 'Microsoft.Insights/', parameters('profileName'))]\",\n \"location\": \"[[parameters('location')]\",\n \"dependsOn\": [],\n \"properties\": {\n \"workspaceId\": \"[[parameters('logAnalytics')]\",\n \"metrics\": [\n {\n \"category\": \"AllMetrics\",\n \"timeGrain\": null,\n \"enabled\": \"[[parameters('metricsEnabled')]\",\n \"retentionPolicy\": {\n \"enabled\": false,\n \"days\": 0\n }\n }\n ],\n \"logs\": [\n {\n \"category\": \"JobLogs\",\n \"enabled\": \"[[parameters('logsEnabled')]\"\n },\n {\n \"category\": \"JobStreams\",\n \"enabled\": \"[[parameters('logsEnabled')]\"\n },\n {\n \"category\": \"DscNodeStatus\",\n \"enabled\": \"[[parameters('logsEnabled')]\"\n },\n {\n \"category\": \"AuditEvent\",\n \"enabled\": \"[[parameters('logsEnabled')]\"\n }\n ]\n }\n }\n ],\n \"outputs\": {}\n },\n \"parameters\": {\n \"logAnalytics\": {\n \"value\": \"[[parameters('logAnalytics')]\"\n },\n \"location\": {\n \"value\": \"[[field('location')]\"\n },\n \"resourceName\": {\n \"value\": \"[[field('name')]\"\n },\n \"profileName\": {\n \"value\": \"[[parameters('profileName')]\"\n },\n \"metricsEnabled\": {\n \"value\": \"[[parameters('metricsEnabled')]\"\n },\n \"logsEnabled\": {\n \"value\": \"[[parameters('logsEnabled')]\"\n }\n }\n }\n }\n }\n }\n }\n }\n}", @@ -156,7 +156,7 @@ "$fxv#84": "{\n \"name\": \"Deploy-SQL-minTLS\",\n \"type\": \"Microsoft.Authorization/policyDefinitions\",\n \"apiVersion\": \"2021-06-01\",\n \"scope\": null,\n \"properties\": {\n \"policyType\": \"Custom\",\n \"mode\": \"Indexed\",\n \"displayName\": \"SQL servers deploys a specific min TLS version requirement.\",\n \"description\": \"Deploys a specific min TLS version requirement and enforce SSL on SQL servers. Enables secure server to client by enforce minimal Tls Version to secure the connection between your database server and your client applications helps protect against 'man in the middle' attacks by encrypting the data stream between the server and your application. This configuration enforces that SSL is always enabled for accessing your database server.\",\n \"metadata\": {\n \"version\": \"1.0.0\",\n \"category\": \"SQL\",\n \"source\": \"https://github.com/Azure/Enterprise-Scale/\",\n \"alzCloudEnvironments\": [\n \"AzureCloud\",\n \"AzureChinaCloud\",\n \"AzureUSGovernment\"\n ]\n },\n \"parameters\": {\n \"effect\": {\n \"type\": \"String\",\n \"defaultValue\": \"DeployIfNotExists\",\n \"allowedValues\": [\n \"DeployIfNotExists\",\n \"Disabled\"\n ],\n \"metadata\": {\n \"displayName\": \"Effect SQL servers\",\n \"description\": \"Enable or disable the execution of the policy minimum TLS version SQL servers\"\n }\n },\n \"minimalTlsVersion\": {\n \"type\": \"String\",\n \"defaultValue\": \"1.2\",\n \"allowedValues\": [\n \"1.2\",\n \"1.1\",\n \"1.0\"\n ],\n \"metadata\": {\n \"displayName\": \"Select version for SQL server\",\n \"description\": \"Select version minimum TLS version SQL servers to enforce\"\n }\n }\n },\n \"policyRule\": {\n \"if\": {\n \"allOf\": [\n {\n \"field\": \"type\",\n \"equals\": \"Microsoft.Sql/servers\"\n },\n {\n \"field\": \"Microsoft.Sql/servers/minimalTlsVersion\",\n \"notequals\": \"[[parameters('minimalTlsVersion')]\"\n }\n ]\n },\n \"then\": {\n \"effect\": \"[[parameters('effect')]\",\n \"details\": {\n \"type\": \"Microsoft.Sql/servers\",\n \"existenceCondition\": {\n \"allOf\": [\n {\n \"field\": \"Microsoft.Sql/servers/minimalTlsVersion\",\n \"equals\": \"[[parameters('minimalTlsVersion')]\"\n }\n ]\n },\n \"name\": \"current\",\n \"roleDefinitionIds\": [\n \"/providers/microsoft.authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635\"\n ],\n \"deployment\": {\n \"properties\": {\n \"mode\": \"Incremental\",\n \"template\": {\n \"$schema\": \"http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#\",\n \"contentVersion\": \"1.0.0.0\",\n \"parameters\": {\n \"resourceName\": {\n \"type\": \"String\"\n },\n \"minimalTlsVersion\": {\n \"type\": \"String\"\n },\n \"location\": {\n \"type\": \"String\"\n }\n },\n \"variables\": {},\n \"resources\": [\n {\n \"type\": \"Microsoft.Sql/servers\",\n \"apiVersion\": \"2019-06-01-preview\",\n \"name\": \"[[concat(parameters('resourceName'))]\",\n \"location\": \"[[parameters('location')]\",\n \"properties\": {\n \"minimalTlsVersion\": \"[[parameters('minimalTlsVersion')]\"\n }\n }\n ],\n \"outputs\": {}\n },\n \"parameters\": {\n \"resourceName\": {\n \"value\": \"[[field('name')]\"\n },\n \"minimalTlsVersion\": {\n \"value\": \"[[parameters('minimalTlsVersion')]\"\n },\n \"location\": {\n \"value\": \"[[field('location')]\"\n }\n }\n }\n }\n }\n }\n }\n }\n}\n", "$fxv#85": "{\n \"name\": \"Deploy-Sql-SecurityAlertPolicies\",\n \"type\": \"Microsoft.Authorization/policyDefinitions\",\n \"apiVersion\": \"2021-06-01\",\n \"scope\": null,\n \"properties\": {\n \"policyType\": \"Custom\",\n \"mode\": \"Indexed\",\n \"displayName\": \"Deploy SQL Database security Alert Policies configuration with email admin accounts\",\n \"description\": \"Deploy the security Alert Policies configuration with email admin accounts when it not exist in current configuration\",\n \"metadata\": {\n \"version\": \"1.1.1\",\n \"category\": \"SQL\",\n \"source\": \"https://github.com/Azure/Enterprise-Scale/\",\n \"alzCloudEnvironments\": [\n \"AzureCloud\",\n \"AzureChinaCloud\",\n \"AzureUSGovernment\"\n ]\n },\n \"parameters\": {\n \"effect\": {\n \"type\": \"String\",\n \"defaultValue\": \"DeployIfNotExists\",\n \"allowedValues\": [\n \"DeployIfNotExists\",\n \"Disabled\"\n ],\n \"metadata\": {\n \"displayName\": \"Effect\",\n \"description\": \"Enable or disable the execution of the policy\"\n }\n },\n \"emailAddresses\":{\n \"type\":\"Array\",\n \"defaultValue\":[\n \"admin@contoso.com\",\n \"admin@fabrikam.com\"\n ]\n }\n },\n \"policyRule\": {\n \"if\": {\n \"field\": \"type\",\n \"equals\": \"Microsoft.Sql/servers/databases\"\n },\n \"then\": {\n \"effect\": \"[[parameters('effect')]\",\n \"details\": {\n \"type\": \"Microsoft.Sql/servers/databases/securityAlertPolicies\",\n \"existenceCondition\": {\n \"allOf\": [\n {\n \"field\": \"Microsoft.Sql/servers/databases/securityAlertPolicies/state\",\n \"equals\": \"Enabled\"\n }\n ]\n },\n \"deployment\": {\n \"properties\": {\n \"mode\": \"Incremental\",\n \"template\": {\n \"$schema\": \"http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#\",\n \"contentVersion\": \"1.0.0.0\",\n \"parameters\": {\n \"location\": {\n \"type\": \"String\"\n },\n \"sqlServerName\": {\n \"type\": \"String\"\n },\n \"sqlServerDataBaseName\": {\n \"type\": \"String\"\n },\n \"emailAddresses\": {\n \"type\": \"Array\"\n }\n },\n \"variables\": {},\n \"resources\": [\n {\n \"name\": \"[[concat(parameters('sqlServerName'),'/',parameters('sqlServerDataBaseName'),'/default')]\",\n \"type\": \"Microsoft.Sql/servers/databases/securityAlertPolicies\",\n \"apiVersion\": \"2018-06-01-preview\",\n \"properties\": {\n \"state\": \"Enabled\",\n \"disabledAlerts\": [\n \"\"\n ],\n \"emailAddresses\": \"[[parameters('emailAddresses')]\",\n \"emailAccountAdmins\": true,\n \"storageEndpoint\": null,\n \"storageAccountAccessKey\": \"\",\n \"retentionDays\": 0\n }\n }\n ],\n \"outputs\": {}\n },\n \"parameters\": {\n \"location\": {\n \"value\": \"[[field('location')]\"\n },\n \"sqlServerName\": {\n \"value\": \"[[first(split(field('fullname'),'/'))]\"\n },\n \"sqlServerDataBaseName\": {\n \"value\": \"[[field('name')]\"\n },\n \"emailAddresses\":{\n \"value\": \"[[parameters('emailAddresses')]\"\n }\n }\n }\n },\n \"roleDefinitionIds\": [\n \"/providers/Microsoft.Authorization/roleDefinitions/056cd41c-7e88-42e1-933e-88ba6a50c9c3\"\n ]\n }\n }\n }\n }\n}\n", "$fxv#86": "{\n \"name\": \"Deploy-Sql-Tde\",\n \"type\": \"Microsoft.Authorization/policyDefinitions\",\n \"apiVersion\": \"2021-06-01\",\n \"scope\": null,\n \"properties\": {\n \"policyType\": \"Custom\",\n \"mode\": \"Indexed\",\n \"displayName\": \"Deploy SQL Database Transparent Data Encryption\",\n \"description\": \"Deploy the Transparent Data Encryption when it is not enabled in the deployment\",\n \"metadata\": {\n \"version\": \"1.1.0\",\n \"category\": \"SQL\",\n \"source\": \"https://github.com/Azure/Enterprise-Scale/\",\n \"alzCloudEnvironments\": [\n \"AzureCloud\",\n \"AzureChinaCloud\",\n \"AzureUSGovernment\"\n ]\n },\n \"parameters\": {\n \"effect\": {\n \"type\": \"String\",\n \"defaultValue\": \"DeployIfNotExists\",\n \"allowedValues\": [\n \"DeployIfNotExists\",\n \"Disabled\"\n ],\n \"metadata\": {\n \"displayName\": \"Effect\",\n \"description\": \"Enable or disable the execution of the policy\"\n }\n },\n \"excludedDatabases\": {\n \"type\": \"Array\",\n \"metadata\":{\n \"displayName\": \"Excluded Databases\",\n \"description\": \"Array of databases that are excluded from this policy\"\n },\n \"defaultValue\": [\n \"master\",\n \"model\",\n \"tempdb\",\n \"msdb\",\n \"resource\"\n ]\n }\n },\n \"policyRule\": {\n \"if\": {\n \"allOf\": [\n {\n \"field\": \"type\",\n \"equals\": \"Microsoft.Sql/servers/databases\"\n },\n {\n \"field\": \"name\",\n \"notIn\": \"[[parameters('excludedDatabases')]\"\n\n }\n ]\n },\n \"then\": {\n \"effect\": \"[[parameters('effect')]\",\n \"details\": {\n \"type\": \"Microsoft.Sql/servers/databases/transparentDataEncryption\",\n \"existenceCondition\": {\n \"allOf\": [\n {\n \"field\": \"Microsoft.Sql/transparentDataEncryption.status\",\n \"equals\": \"Enabled\"\n }\n ]\n },\n \"deployment\": {\n \"properties\": {\n \"mode\": \"Incremental\",\n \"template\": {\n \"$schema\": \"http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#\",\n \"contentVersion\": \"1.0.0.0\",\n \"parameters\": {\n \"location\": {\n \"type\": \"String\"\n },\n \"sqlServerName\": {\n \"type\": \"String\"\n },\n \"sqlServerDataBaseName\": {\n \"type\": \"String\"\n }\n },\n \"variables\": {},\n \"resources\": [\n {\n \"name\": \"[[concat( parameters('sqlServerName'),'/',parameters('sqlServerDataBaseName'),'/current')]\",\n \"type\": \"Microsoft.Sql/servers/databases/transparentDataEncryption\",\n \"apiVersion\": \"2014-04-01\",\n \"properties\": {\n \"status\": \"Enabled\"\n }\n }\n ],\n \"outputs\": {}\n },\n \"parameters\": {\n \"location\": {\n \"value\": \"[[field('location')]\"\n },\n \"sqlServerName\": {\n \"value\": \"[[first(split(field('fullname'),'/'))]\"\n },\n \"sqlServerDataBaseName\": {\n \"value\": \"[[field('name')]\"\n }\n }\n }\n },\n \"roleDefinitionIds\": [\n \"/providers/Microsoft.Authorization/roleDefinitions/056cd41c-7e88-42e1-933e-88ba6a50c9c3\"\n ]\n }\n }\n }\n }\n}", - "$fxv#87": "{\n \"name\": \"Deploy-Sql-vulnerabilityAssessments\",\n \"type\": \"Microsoft.Authorization/policyDefinitions\",\n \"apiVersion\": \"2021-06-01\",\n \"scope\": null,\n \"properties\": {\n \"policyType\": \"Custom\",\n \"mode\": \"Indexed\",\n \"displayName\": \"Deploy SQL Database vulnerability Assessments\",\n \"description\": \"Deploy SQL Database vulnerability Assessments when it not exist in the deployment. To the specific storage account in the parameters\",\n \"metadata\": {\n \"version\": \"1.0.0\",\n \"category\": \"SQL\",\n \"source\": \"https://github.com/Azure/Enterprise-Scale/\",\n \"alzCloudEnvironments\": [\n \"AzureCloud\",\n \"AzureChinaCloud\",\n \"AzureUSGovernment\"\n ]\n },\n \"parameters\": {\n \"vulnerabilityAssessmentsEmail\": {\n \"type\": \"String\",\n \"metadata\": {\n \"description\": \"The email address to send alerts\",\n \"displayName\": \"The email address to send alerts\"\n }\n },\n \"vulnerabilityAssessmentsStorageID\": {\n \"type\": \"String\",\n \"metadata\": {\n \"description\": \"The storage account ID to store assessments\",\n \"displayName\": \"The storage account ID to store assessments\"\n }\n },\n \"effect\": {\n \"type\": \"String\",\n \"defaultValue\": \"DeployIfNotExists\",\n \"allowedValues\": [\n \"DeployIfNotExists\",\n \"Disabled\"\n ],\n \"metadata\": {\n \"displayName\": \"Effect\",\n \"description\": \"Enable or disable the execution of the policy\"\n }\n }\n },\n \"policyRule\": {\n \"if\": {\n \"field\": \"type\",\n \"equals\": \"Microsoft.Sql/servers/databases\"\n },\n \"then\": {\n \"effect\": \"[[parameters('effect')]\",\n \"details\": {\n \"type\": \"Microsoft.Sql/servers/databases/vulnerabilityAssessments\",\n \"existenceCondition\": {\n \"allOf\": [\n {\n \"field\": \"Microsoft.Sql/servers/databases/vulnerabilityAssessments/recurringScans.emails\",\n \"equals\": \"[[parameters('vulnerabilityAssessmentsEmail')]\"\n },\n {\n \"field\": \"Microsoft.Sql/servers/databases/vulnerabilityAssessments/recurringScans.isEnabled\",\n \"equals\": true\n }\n ]\n },\n \"deployment\": {\n \"properties\": {\n \"mode\": \"Incremental\",\n \"template\": {\n \"$schema\": \"http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#\",\n \"contentVersion\": \"1.0.0.0\",\n \"parameters\": {\n \"location\": {\n \"type\": \"String\"\n },\n \"sqlServerName\": {\n \"type\": \"String\"\n },\n \"sqlServerDataBaseName\": {\n \"type\": \"String\"\n },\n \"vulnerabilityAssessmentsEmail\": {\n \"type\": \"String\"\n },\n \"vulnerabilityAssessmentsStorageID\": {\n \"type\": \"String\"\n }\n },\n \"variables\": {},\n \"resources\": [\n {\n \"name\": \"[[concat(parameters('sqlServerName'),'/',parameters('sqlServerDataBaseName'),'/default')]\",\n \"type\": \"Microsoft.Sql/servers/databases/vulnerabilityAssessments\",\n \"apiVersion\": \"2017-03-01-preview\",\n \"properties\": {\n \"storageContainerPath\": \"[[concat('https://', last( split(parameters('vulnerabilityAssessmentsStorageID') , '/') ) , '.blob.core.windows.net/vulneraabilitylogs')]\",\n \"storageAccountAccessKey\": \"[[listkeys(parameters('vulnerabilityAssessmentsStorageID'), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value]\",\n \"recurringScans\": {\n \"isEnabled\": true,\n \"emailSubscriptionAdmins\": false,\n \"emails\": [\n \"[[parameters('vulnerabilityAssessmentsEmail')]\"\n ]\n }\n }\n }\n ],\n \"outputs\": {}\n },\n \"parameters\": {\n \"location\": {\n \"value\": \"[[field('location')]\"\n },\n \"sqlServerName\": {\n \"value\": \"[[first(split(field('fullname'),'/'))]\"\n },\n \"sqlServerDataBaseName\": {\n \"value\": \"[[field('name')]\"\n },\n \"vulnerabilityAssessmentsEmail\": {\n \"value\": \"[[parameters('vulnerabilityAssessmentsEmail')]\"\n },\n \"vulnerabilityAssessmentsStorageID\": {\n \"value\": \"[[parameters('vulnerabilityAssessmentsStorageID')]\"\n }\n }\n }\n },\n \"roleDefinitionIds\": [\n \"/providers/Microsoft.Authorization/roleDefinitions/056cd41c-7e88-42e1-933e-88ba6a50c9c3\",\n \"/providers/Microsoft.Authorization/roleDefinitions/749f88d5-cbae-40b8-bcfc-e573ddc772fa\"\n ]\n }\n }\n }\n }\n}\n", + "$fxv#87": "{\n \"name\": \"Deploy-Sql-vulnerabilityAssessments\",\n \"type\": \"Microsoft.Authorization/policyDefinitions\",\n \"apiVersion\": \"2021-06-01\",\n \"scope\": null,\n \"properties\": {\n \"policyType\": \"Custom\",\n \"mode\": \"Indexed\",\n \"displayName\": \"Deploy SQL Database vulnerability Assessments\",\n \"description\": \"Deploy SQL Database vulnerability Assessments when it not exist in the deployment. To the specific storage account in the parameters\",\n \"metadata\": {\n \"version\": \"1.0.1\",\n \"category\": \"SQL\",\n \"source\": \"https://github.com/Azure/Enterprise-Scale/\",\n \"alzCloudEnvironments\": [\n \"AzureCloud\",\n \"AzureChinaCloud\",\n \"AzureUSGovernment\"\n ]\n },\n \"parameters\": {\n \"vulnerabilityAssessmentsEmail\": {\n \"type\": \"String\",\n \"metadata\": {\n \"description\": \"The email address to send alerts. For multiple emails, format in the following 'email1@contoso.com;email2@contoso.com'\",\n \"displayName\": \"The email address to send alerts. For multiple emails, format in the following 'email1@contoso.com;email2@contoso.com'\"\n }\n },\n \"vulnerabilityAssessmentsStorageID\": {\n \"type\": \"String\",\n \"metadata\": {\n \"description\": \"The storage account ID to store assessments\",\n \"displayName\": \"The storage account ID to store assessments\"\n }\n },\n \"effect\": {\n \"type\": \"String\",\n \"defaultValue\": \"DeployIfNotExists\",\n \"allowedValues\": [\n \"DeployIfNotExists\",\n \"Disabled\"\n ],\n \"metadata\": {\n \"displayName\": \"Effect\",\n \"description\": \"Enable or disable the execution of the policy\"\n }\n }\n },\n \"policyRule\": {\n \"if\": {\n \"field\": \"type\",\n \"equals\": \"Microsoft.Sql/servers/databases\"\n },\n \"then\": {\n \"effect\": \"[[parameters('effect')]\",\n \"details\": {\n \"type\": \"Microsoft.Sql/servers/databases/vulnerabilityAssessments\",\n \"existenceCondition\": {\n \"allOf\": [\n {\n \"field\": \"Microsoft.Sql/servers/databases/vulnerabilityAssessments/recurringScans.emails\",\n \"equals\": \"[[parameters('vulnerabilityAssessmentsEmail')]\"\n },\n {\n \"field\": \"Microsoft.Sql/servers/databases/vulnerabilityAssessments/recurringScans.isEnabled\",\n \"equals\": true\n }\n ]\n },\n \"deployment\": {\n \"properties\": {\n \"mode\": \"Incremental\",\n \"template\": {\n \"$schema\": \"http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#\",\n \"contentVersion\": \"1.0.0.0\",\n \"parameters\": {\n \"location\": {\n \"type\": \"String\"\n },\n \"sqlServerName\": {\n \"type\": \"String\"\n },\n \"sqlServerDataBaseName\": {\n \"type\": \"String\"\n },\n \"vulnerabilityAssessmentsEmail\": {\n \"type\": \"String\"\n },\n \"vulnerabilityAssessmentsStorageID\": {\n \"type\": \"String\"\n }\n },\n \"variables\": {},\n \"resources\": [\n {\n \"name\": \"[[concat(parameters('sqlServerName'),'/',parameters('sqlServerDataBaseName'),'/default')]\",\n \"type\": \"Microsoft.Sql/servers/databases/vulnerabilityAssessments\",\n \"apiVersion\": \"2017-03-01-preview\",\n \"properties\": {\n \"storageContainerPath\": \"[[concat('https://', last( split(parameters('vulnerabilityAssessmentsStorageID') , '/') ) , '.blob.core.windows.net/vulneraabilitylogs')]\",\n \"storageAccountAccessKey\": \"[[listkeys(parameters('vulnerabilityAssessmentsStorageID'), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value]\",\n \"recurringScans\": {\n \"isEnabled\": true,\n \"emailSubscriptionAdmins\": false,\n \"emails\": [\n \"[[parameters('vulnerabilityAssessmentsEmail')]\"\n ]\n }\n }\n }\n ],\n \"outputs\": {}\n },\n \"parameters\": {\n \"location\": {\n \"value\": \"[[field('location')]\"\n },\n \"sqlServerName\": {\n \"value\": \"[[first(split(field('fullname'),'/'))]\"\n },\n \"sqlServerDataBaseName\": {\n \"value\": \"[[field('name')]\"\n },\n \"vulnerabilityAssessmentsEmail\": {\n \"value\": \"[[parameters('vulnerabilityAssessmentsEmail')]\"\n },\n \"vulnerabilityAssessmentsStorageID\": {\n \"value\": \"[[parameters('vulnerabilityAssessmentsStorageID')]\"\n }\n }\n }\n },\n \"roleDefinitionIds\": [\n \"/providers/Microsoft.Authorization/roleDefinitions/056cd41c-7e88-42e1-933e-88ba6a50c9c3\",\n \"/providers/Microsoft.Authorization/roleDefinitions/749f88d5-cbae-40b8-bcfc-e573ddc772fa\",\n \"/providers/Microsoft.Authorization/roleDefinitions/17d1049b-9a84-46fb-8f53-869881c3d3ab\"\n ]\n }\n }\n }\n }\n}\n", "$fxv#88": "{\n \"name\": \"Deploy-SqlMi-minTLS\",\n \"type\": \"Microsoft.Authorization/policyDefinitions\",\n \"apiVersion\": \"2021-06-01\",\n \"scope\": null,\n \"properties\": {\n \"policyType\": \"Custom\",\n \"mode\": \"Indexed\",\n \"displayName\": \"SQL managed instances deploy a specific min TLS version requirement.\",\n \"description\": \"Deploy a specific min TLS version requirement and enforce SSL on SQL managed instances. Enables secure server to client by enforce minimal Tls Version to secure the connection between your database server and your client applications helps protect against 'man in the middle' attacks by encrypting the data stream between the server and your application. This configuration enforces that SSL is always enabled for accessing your database server.\",\n \"metadata\": {\n \"version\": \"1.0.0\",\n \"category\": \"SQL\",\n \"source\": \"https://github.com/Azure/Enterprise-Scale/\",\n \"alzCloudEnvironments\": [\n \"AzureCloud\",\n \"AzureChinaCloud\",\n \"AzureUSGovernment\"\n ]\n },\n \"parameters\": {\n \"effect\": {\n \"type\": \"String\",\n \"defaultValue\": \"DeployIfNotExists\",\n \"allowedValues\": [\n \"DeployIfNotExists\",\n \"Disabled\"\n ],\n \"metadata\": {\n \"displayName\": \"Effect SQL servers\",\n \"description\": \"Enable or disable the execution of the policy minimum TLS version SQL servers\"\n }\n },\n \"minimalTlsVersion\": {\n \"type\": \"String\",\n \"defaultValue\": \"1.2\",\n \"allowedValues\": [\n \"1.2\",\n \"1.1\",\n \"1.0\"\n ],\n \"metadata\": {\n \"displayName\": \"Select version for SQL server\",\n \"description\": \"Select version minimum TLS version SQL servers to enforce\"\n }\n }\n },\n \"policyRule\": {\n \"if\": {\n \"allOf\": [\n {\n \"field\": \"type\",\n \"equals\": \"Microsoft.Sql/managedInstances\"\n },\n {\n \"field\": \"Microsoft.Sql/managedInstances/minimalTlsVersion\",\n \"notequals\": \"[[parameters('minimalTlsVersion')]\"\n }\n ]\n },\n \"then\": {\n \"effect\": \"[[parameters('effect')]\",\n \"details\": {\n \"type\": \"Microsoft.Sql/managedInstances\",\n \"existenceCondition\": {\n \"allOf\": [\n {\n \"field\": \"Microsoft.Sql/managedInstances/minimalTlsVersion\",\n \"equals\": \"[[parameters('minimalTlsVersion')]\"\n }\n ]\n },\n \"name\": \"current\",\n \"roleDefinitionIds\": [\n \"/providers/microsoft.authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635\"\n ],\n \"deployment\": {\n \"properties\": {\n \"mode\": \"Incremental\",\n \"template\": {\n \"$schema\": \"http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#\",\n \"contentVersion\": \"1.0.0.0\",\n \"parameters\": {\n \"resourceName\": {\n \"type\": \"String\"\n },\n \"minimalTlsVersion\": {\n \"type\": \"String\"\n },\n \"location\": {\n \"type\": \"String\"\n }\n },\n \"variables\": {},\n \"resources\": [\n {\n \"type\": \"Microsoft.Sql/managedInstances\",\n \"apiVersion\": \"2020-02-02-preview\",\n \"name\": \"[[concat(parameters('resourceName'))]\",\n \"location\": \"[[parameters('location')]\",\n \"properties\": {\n \"minimalTlsVersion\": \"[[parameters('minimalTlsVersion')]\"\n }\n }\n ],\n \"outputs\": {}\n },\n \"parameters\": {\n \"resourceName\": {\n \"value\": \"[[field('name')]\"\n },\n \"minimalTlsVersion\": {\n \"value\": \"[[parameters('minimalTlsVersion')]\"\n },\n \"location\": {\n \"value\": \"[[field('location')]\"\n }\n }\n }\n }\n }\n }\n }\n }\n}\n", "$fxv#89": "{\n \"name\": \"Deploy-Storage-sslEnforcement\",\n \"type\": \"Microsoft.Authorization/policyDefinitions\",\n \"apiVersion\": \"2021-06-01\",\n \"scope\": null,\n \"properties\": {\n \"policyType\": \"Custom\",\n \"mode\": \"Indexed\",\n \"displayName\": \"Azure Storage deploy a specific min TLS version requirement and enforce SSL/HTTPS \",\n \"description\": \"Deploy a specific min TLS version requirement and enforce SSL on Azure Storage. Enables secure server to client by enforce minimal Tls Version to secure the connection between your database server and your client applications helps protect against 'man in the middle' attacks by encrypting the data stream between the server and your application. This configuration enforces that SSL is always enabled for accessing your Azure Storage.\",\n \"metadata\": {\n \"version\": \"1.1.0\",\n \"category\": \"Storage\",\n \"source\": \"https://github.com/Azure/Enterprise-Scale/\",\n \"alzCloudEnvironments\": [\n \"AzureCloud\",\n \"AzureChinaCloud\",\n \"AzureUSGovernment\"\n ]\n },\n \"parameters\": {\n \"effect\": {\n \"type\": \"String\",\n \"defaultValue\": \"DeployIfNotExists\",\n \"allowedValues\": [\n \"DeployIfNotExists\",\n \"Disabled\"\n ],\n \"metadata\": {\n \"displayName\": \"Effect Azure Storage\",\n \"description\": \"Enable or disable the execution of the policy minimum TLS version Azure STorage\"\n }\n },\n \"minimumTlsVersion\": {\n \"type\": \"String\",\n \"defaultValue\": \"TLS1_2\",\n \"allowedValues\": [\n \"TLS1_2\",\n \"TLS1_1\",\n \"TLS1_0\"\n ],\n \"metadata\": {\n \"displayName\": \"Select TLS version for Azure Storage server\",\n \"description\": \"Select version minimum TLS version Azure STorage to enforce\"\n }\n }\n },\n \"policyRule\": {\n \"if\": {\n \"allOf\": [\n {\n \"field\": \"type\",\n \"equals\": \"Microsoft.Storage/storageAccounts\"\n },\n {\n \"anyOf\": [\n {\n \"field\": \"Microsoft.Storage/storageAccounts/supportsHttpsTrafficOnly\",\n \"notEquals\": \"true\"\n },\n {\n \"field\": \"Microsoft.Storage/storageAccounts/minimumTlsVersion\",\n \"notEquals\": \"[[parameters('minimumTlsVersion')]\"\n }\n ]\n }\n ]\n },\n \"then\": {\n \"effect\": \"[[parameters('effect')]\",\n \"details\": {\n \"type\": \"Microsoft.Storage/storageAccounts\",\n \"existenceCondition\": {\n \"allOf\": [\n {\n \"field\": \"Microsoft.Storage/storageAccounts/supportsHttpsTrafficOnly\",\n \"equals\": \"true\"\n },\n {\n \"field\": \"Microsoft.Storage/storageAccounts/minimumTlsVersion\",\n \"equals\": \"[[parameters('minimumTlsVersion')]\"\n }\n ]\n },\n \"name\": \"current\",\n \"roleDefinitionIds\": [\n \"/providers/microsoft.authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635\"\n ],\n \"deployment\": {\n \"properties\": {\n \"mode\": \"Incremental\",\n \"template\": {\n \"$schema\": \"http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#\",\n \"contentVersion\": \"1.0.0.0\",\n \"parameters\": {\n \"resourceName\": {\n \"type\": \"String\"\n },\n \"minimumTlsVersion\": {\n \"type\": \"String\"\n },\n \"location\": {\n \"type\": \"String\"\n }\n },\n \"variables\": {},\n \"resources\": [\n {\n \"type\": \"Microsoft.Storage/storageAccounts\",\n \"apiVersion\": \"2019-06-01\",\n \"name\": \"[[concat(parameters('resourceName'))]\",\n \"location\": \"[[parameters('location')]\",\n \"properties\": {\n \"supportsHttpsTrafficOnly\": true,\n \"minimumTlsVersion\": \"[[parameters('minimumTlsVersion')]\"\n }\n }\n ],\n \"outputs\": {}\n },\n \"parameters\": {\n \"resourceName\": {\n \"value\": \"[[field('name')]\"\n },\n \"minimumTlsVersion\": {\n \"value\": \"[[parameters('minimumTlsVersion')]\"\n },\n \"location\": {\n \"value\": \"[[field('location')]\"\n }\n }\n }\n }\n }\n }\n }\n }\n}\n", "$fxv#9": "{\n \"name\": \"Deny-MySql-http\",\n \"type\": \"Microsoft.Authorization/policyDefinitions\",\n \"apiVersion\": \"2021-06-01\",\n \"scope\": null,\n \"properties\": {\n \"policyType\": \"Custom\",\n \"mode\": \"Indexed\",\n \"displayName\": \"MySQL database servers enforce SSL connections.\",\n \"description\": \"Azure Database for MySQL supports connecting your Azure Database for MySQL server to client applications using Secure Sockets Layer (SSL). Enforcing SSL connections between your database server and your client applications helps protect against 'man in the middle' attacks by encrypting the data stream between the server and your application. This configuration enforces that SSL is always enabled for accessing your database server.\",\n \"metadata\": {\n \"version\": \"1.0.0\",\n \"category\": \"SQL\",\n \"source\": \"https://github.com/Azure/Enterprise-Scale/\",\n \"alzCloudEnvironments\": [\n \"AzureCloud\",\n \"AzureChinaCloud\",\n \"AzureUSGovernment\"\n ]\n },\n \"parameters\": {\n \"effect\": {\n \"type\": \"String\",\n \"defaultValue\": \"Deny\",\n \"allowedValues\": [\n \"Audit\",\n \"Disabled\",\n \"Deny\"\n ],\n \"metadata\": {\n \"displayName\": \"Effect\",\n \"description\": \"Enable or disable the execution of the policy\"\n }\n },\n \"minimalTlsVersion\": {\n \"type\": \"String\",\n \"defaultValue\": \"TLS1_2\",\n \"allowedValues\": [\n \"TLS1_2\",\n \"TLS1_0\",\n \"TLS1_1\",\n \"TLSEnforcementDisabled\"\n ],\n \"metadata\": {\n \"displayName\": \"Select version minimum TLS for MySQL server\",\n \"description\": \"Select version minimum TLS version Azure Database for MySQL server to enforce\"\n }\n }\n },\n \"policyRule\": {\n \"if\": {\n \"allOf\": [\n {\n \"field\": \"type\",\n \"equals\": \"Microsoft.DBforMySQL/servers\"\n },\n {\n \"anyOf\": [\n {\n \"field\": \"Microsoft.DBforMySQL/servers/sslEnforcement\",\n \"exists\": \"false\"\n },\n {\n \"field\": \"Microsoft.DBforMySQL/servers/sslEnforcement\",\n \"notEquals\": \"Enabled\"\n },\n {\n \"field\": \"Microsoft.DBforMySQL/servers/minimalTlsVersion\",\n \"notequals\": \"[[parameters('minimalTlsVersion')]\"\n }\n ]\n }\n ]\n },\n \"then\": {\n \"effect\": \"[[parameters('effect')]\"\n }\n }\n }\n}\n", diff --git a/eslzArm/managementGroupTemplates/roleDefinitions/README.md b/eslzArm/managementGroupTemplates/roleDefinitions/README.md new file mode 100644 index 0000000000..ac039d2c54 --- /dev/null +++ b/eslzArm/managementGroupTemplates/roleDefinitions/README.md @@ -0,0 +1,16 @@ +# Information relating to `customRoleDefinitions.json` + +The `customRoleDefinitions.json` deployment template provides a unified deployment experience for creating all Role Definitions as recommended for the Azure landing zone reference implementation. + +This template is designed to work across the following clouds, ensuring the supported combination of roles are created in the customer environment: + +- AzureCloud (Public) +- AzureChinaCloud (Azure China / 21Vianet) +- AzureUSGovernment (US Government) + +> **IMPORTANT:** +> Please note that the `customRoleDefinitions.json` file located in this directory is programmatically generated and **must not** be manually edited. +> When making changes to policies, please refer to the [roles.bicep](../../../src/templates/roles.bicep) file. + + +*further guidance to follow* diff --git a/eslzArm/managementGroupTemplates/roleDefinitions/customRoleDefinitions.json b/eslzArm/managementGroupTemplates/roleDefinitions/customRoleDefinitions.json new file mode 100644 index 0000000000..e8dec1d79e --- /dev/null +++ b/eslzArm/managementGroupTemplates/roleDefinitions/customRoleDefinitions.json @@ -0,0 +1,169 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-08-01/managementGroupDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.13.1.58284", + "templateHash": "12224779871540963425" + } + }, + "variables": { + "$fxv#0": { + "name": "c9a07a05-a1fc-53fe-a565-5eed25597c03", + "type": "Microsoft.Authorization/roleDefinitions", + "apiVersion": "2022-04-01", + "properties": { + "roleName": "Application-Owners", + "description": "Contributor role granted for application/operations team at resource group level", + "type": "customRole", + "permissions": [ + { + "actions": [ + "*" + ], + "notActions": [ + "Microsoft.Authorization/*/write", + "Microsoft.Network/publicIPAddresses/write", + "Microsoft.Network/virtualNetworks/write", + "Microsoft.KeyVault/locations/deletedVaults/purge/action" + ], + "dataActions": [], + "notDataActions": [] + } + ], + "assignableScopes": [ + "/providers/Microsoft.Management/managementGroups/contoso" + ] + } + }, + "$fxv#1": { + "name": "dc726155-3983-5405-b446-9bb27b94e02c", + "type": "Microsoft.Authorization/roleDefinitions", + "apiVersion": "2022-04-01", + "properties": { + "roleName": "Network-Management", + "description": "Platform-wide global connectivity management: virtual networks, UDRs, NSGs, NVAs, VPN, Azure ExpressRoute, and others", + "type": "customRole", + "permissions": [ + { + "actions": [ + "*/read", + "Microsoft.Network/*", + "Microsoft.Resources/deployments/*", + "Microsoft.Support/*" + ], + "notActions": [], + "dataActions": [], + "notDataActions": [] + } + ], + "assignableScopes": [ + "/providers/Microsoft.Management/managementGroups/contoso" + ] + } + }, + "$fxv#2": { + "name": "d3584a79-4f0d-5980-aa3c-7a76ba783b76", + "type": "Microsoft.Authorization/roleDefinitions", + "apiVersion": "2022-04-01", + "properties": { + "roleName": "Security-Operations", + "description": "Security Administrator role with a horizontal view across the entire Azure estate and the Azure Key Vault purge policy.", + "type": "customRole", + "permissions": [ + { + "actions": [ + "*/read", + "*/register/action", + "Microsoft.KeyVault/locations/deletedVaults/purge/action", + "Microsoft.PolicyInsights/*", + "Microsoft.Authorization/policyAssignments/*", + "Microsoft.Authorization/policyDefinitions/*", + "Microsoft.Authorization/policyExemptions/*", + "Microsoft.Authorization/policySetDefinitions/*", + "Microsoft.Insights/alertRules/*", + "Microsoft.Resources/deployments/*", + "Microsoft.Security/*", + "Microsoft.Support/*" + ], + "notActions": [], + "dataActions": [], + "notDataActions": [] + } + ], + "assignableScopes": [ + "/providers/Microsoft.Management/managementGroups/contoso" + ] + } + }, + "$fxv#3": { + "name": "402344ce-48c4-5ac1-9320-16726050f964", + "type": "Microsoft.Authorization/roleDefinitions", + "apiVersion": "2022-04-01", + "properties": { + "roleName": "Subscription-Owner", + "description": "Delegated role for subscription owner generated from subscription Owner role", + "type": "customRole", + "permissions": [ + { + "actions": [ + "*" + ], + "notActions": [ + "Microsoft.Authorization/*/write", + "Microsoft.Network/vpnGateways/*", + "Microsoft.Network/expressRouteCircuits/*", + "Microsoft.Network/routeTables/write", + "Microsoft.Network/vpnSites/*" + ], + "dataActions": [], + "notDataActions": [] + } + ], + "assignableScopes": [ + "/providers/Microsoft.Management/managementGroups/contoso" + ] + } + }, + "cloudEnv": "[environment().name]", + "loadRoleDefinitions": { + "All": [ + "[variables('$fxv#0')]", + "[variables('$fxv#1')]", + "[variables('$fxv#2')]", + "[variables('$fxv#3')]" + ], + "AzureCloud": [], + "AzureChinaCloud": [], + "AzureUSGovernment": [] + }, + "roleDefinitionsByCloudType": { + "All": "[variables('loadRoleDefinitions').All]", + "AzureCloud": "[variables('loadRoleDefinitions').AzureCloud]", + "AzureChinaCloud": "[variables('loadRoleDefinitions').AzureChinaCloud]", + "AzureUSGovernment": "[variables('loadRoleDefinitions').AzureUSGovernment]" + }, + "roleDefinitions": "[concat(variables('roleDefinitionsByCloudType').All, variables('roleDefinitionsByCloudType')[variables('cloudEnv')])]" + }, + "resources": [ + { + "copy": { + "name": "RoleDefinitions", + "count": "[length(variables('roleDefinitions'))]" + }, + "type": "Microsoft.Authorization/roleDefinitions", + "apiVersion": "2022-04-01", + "name": "[guid(variables('roleDefinitions')[copyIndex()].properties.roleName, managementGroup().name)]", + "properties": { + "roleName": "[format('[{0}] {1}', managementGroup().name, variables('roleDefinitions')[copyIndex()].properties.roleName)]", + "description": "[variables('roleDefinitions')[copyIndex()].properties.description]", + "type": "[variables('roleDefinitions')[copyIndex()].properties.type]", + "permissions": "[variables('roleDefinitions')[copyIndex()].properties.permissions]", + "assignableScopes": [ + "[managementGroup().id]" + ] + } + } + ] +} \ No newline at end of file diff --git a/eslzArm/subscriptionTemplates/logAnalyticsSolutions.json b/eslzArm/subscriptionTemplates/logAnalyticsSolutions.json index ae199128e7..69d635cf2c 100644 --- a/eslzArm/subscriptionTemplates/logAnalyticsSolutions.json +++ b/eslzArm/subscriptionTemplates/logAnalyticsSolutions.json @@ -65,17 +65,6 @@ "description": "Select whether update mgmt solution should be enabled or not." } }, - "enableActivityLog": { - "type": "string", - "allowedValues": [ - "Yes", - "No" - ], - "defaultValue": "Yes", - "metadata": { - "description": "Select whether activity log solution should be enabled or not." - } - }, "enableVmInsights": { "type": "string", "allowedValues": [ @@ -151,10 +140,6 @@ "name": "[concat('Updates', '(', parameters('workspaceName'), ')')]", "marketplaceName": "Updates" }, - "azureActivity": { - "name": "[concat('AzureActivity', '(', parameters('workspaceName'), ')')]", - "marketplaceName": "AzureActivity" - }, "sqlAssessment": { "name": "[concat('SQLAssessment', '(', parameters('workspaceName'), ')')]", "marketplaceName": "SQLAssessment" @@ -212,23 +197,6 @@ "publisher": "Microsoft" } }, - { - // Conditionally deploy solution for activity log - "condition": "[equals(parameters('enableActivityLog'), 'Yes')]", - "apiVersion": "2015-11-01-preview", - "type": "Microsoft.OperationsManagement/solutions", - "name": "[variables('solutions').azureActivity.name]", - "location": "[parameters('workspaceRegion')]", - "properties": { - "workspaceResourceId": "[variables('laResourceId')]" - }, - "plan": { - "name": "[variables('solutions').azureActivity.name]", - "product": "[concat('OMSGallery/', variables('solutions').azureActivity.marketplaceName)]", - "promotionCode": "", - "publisher": "Microsoft" - } - }, { // Conditionally deploy solution for change tracking "condition": "[equals(parameters('enableChangeTracking'), 'Yes')]", diff --git a/examples/landing-zones/README.md b/examples/landing-zones/README.md index f994e85f52..8d5b700d66 100644 --- a/examples/landing-zones/README.md +++ b/examples/landing-zones/README.md @@ -103,4 +103,4 @@ In order to create subscriptions at scale using ARM templates, we strongly recom It is recommend to enable the management group hierarchy settings in your Azure tenant to ensure that role-based-access-control is required to create, update, and delete management groups. By enabling this setting default management group for new subscription has to be specified. - ![management group hierarchy settings](../../docs/media/mg-hierarchy-settings.png) + ![management group hierarchy settings](../../docs/wiki/media/mg-hierarchy-settings.png) diff --git a/examples/management-groups/README.md b/examples/management-groups/README.md index ee54a5fdbc..48f824b83a 100644 --- a/examples/management-groups/README.md +++ b/examples/management-groups/README.md @@ -59,4 +59,4 @@ In order to create subscriptions at scale using ARM templates, we strongly recom It is recommend to enable the management group hierarchy settings in your Azure tenant to ensure that role-based-access-control is required to create, update, and delete management groups. - ![management group hierarchy settings](../../docs/media/mg-hierarchy-settings.png) + ![management group hierarchy settings](../../docs/wiki/media/mg-hierarchy-settings.png) diff --git a/examples/policies/policy-definition/README.md b/examples/policies/policy-definition/README.md index a1387a3140..e6c49ef0ff 100644 --- a/examples/policies/policy-definition/README.md +++ b/examples/policies/policy-definition/README.md @@ -34,7 +34,7 @@ The ARM template provided in this folder shows how a new policy definition is cr ## Deploy using AzOps -See these [instructions]( https://github.com/azure/azops/wiki/deployments) for how to deploy ARM templates with the AzOps GitHub Actions/DevOps pipeline. +See these [instructions](https://github.com/azure/azops/wiki/deployments) for how to deploy ARM templates with the AzOps GitHub Actions/DevOps pipeline. ## Deploy using Azure PowerShell diff --git a/src/resources/Microsoft.Authorization/policyDefinitions/Deny-MachineLearning-PublicAccessWhenBehindVnet.json b/src/resources/Microsoft.Authorization/policyDefinitions/Deny-MachineLearning-PublicAccessWhenBehindVnet.json index ca4b2bd07b..18d6428dc4 100644 --- a/src/resources/Microsoft.Authorization/policyDefinitions/Deny-MachineLearning-PublicAccessWhenBehindVnet.json +++ b/src/resources/Microsoft.Authorization/policyDefinitions/Deny-MachineLearning-PublicAccessWhenBehindVnet.json @@ -6,10 +6,10 @@ "properties": { "policyType": "Custom", "mode": "Indexed", - "displayName": "Deny public acces behind vnet to Azure Machine Learning workspace", + "displayName": "Deny public access behind vnet to Azure Machine Learning workspace", "description": "Deny public access behind vnet to Azure Machine Learning workspaces.", "metadata": { - "version": "1.0.0", + "version": "1.0.1", "category": "Machine Learning", "source": "https://github.com/Azure/Enterprise-Scale/", "alzCloudEnvironments": [ diff --git a/src/resources/Microsoft.Authorization/policyDefinitions/Deploy-ASC-SecurityContacts.json b/src/resources/Microsoft.Authorization/policyDefinitions/Deploy-ASC-SecurityContacts.json index e478d4e294..b8241b9948 100644 --- a/src/resources/Microsoft.Authorization/policyDefinitions/Deploy-ASC-SecurityContacts.json +++ b/src/resources/Microsoft.Authorization/policyDefinitions/Deploy-ASC-SecurityContacts.json @@ -9,7 +9,7 @@ "displayName": "Deploy Microsoft Defender for Cloud Security Contacts", "description": "Deploy Microsoft Defender for Cloud Security Contacts", "metadata": { - "version": "1.0.0", + "version": "1.1.0", "category": "Security Center", "source": "https://github.com/Azure/Enterprise-Scale/", "alzCloudEnvironments": [ @@ -101,6 +101,9 @@ "parameters": { "emailSecurityContact": { "value": "[[parameters('emailSecurityContact')]" + }, + "minimalSeverity": { + "value": "[[parameters('minimalSeverity')]" } }, "template": { @@ -112,6 +115,12 @@ "metadata": { "description": "Security contacts email address" } + }, + "minimalSeverity": { + "type": "string", + "metadata": { + "description": "Minimal severity level reported" + } } }, "variables": {}, diff --git a/src/resources/Microsoft.Authorization/policyDefinitions/Deploy-Sql-vulnerabilityAssessments.json b/src/resources/Microsoft.Authorization/policyDefinitions/Deploy-Sql-vulnerabilityAssessments.json index b10a34b80d..861f44cd0c 100644 --- a/src/resources/Microsoft.Authorization/policyDefinitions/Deploy-Sql-vulnerabilityAssessments.json +++ b/src/resources/Microsoft.Authorization/policyDefinitions/Deploy-Sql-vulnerabilityAssessments.json @@ -9,7 +9,7 @@ "displayName": "Deploy SQL Database vulnerability Assessments", "description": "Deploy SQL Database vulnerability Assessments when it not exist in the deployment. To the specific storage account in the parameters", "metadata": { - "version": "1.0.0", + "version": "1.0.1", "category": "SQL", "source": "https://github.com/Azure/Enterprise-Scale/", "alzCloudEnvironments": [ @@ -22,8 +22,8 @@ "vulnerabilityAssessmentsEmail": { "type": "String", "metadata": { - "description": "The email address to send alerts", - "displayName": "The email address to send alerts" + "description": "The email address to send alerts. For multiple emails, format in the following 'email1@contoso.com;email2@contoso.com'", + "displayName": "The email address to send alerts. For multiple emails, format in the following 'email1@contoso.com;email2@contoso.com'" } }, "vulnerabilityAssessmentsStorageID": { @@ -132,7 +132,8 @@ }, "roleDefinitionIds": [ "/providers/Microsoft.Authorization/roleDefinitions/056cd41c-7e88-42e1-933e-88ba6a50c9c3", - "/providers/Microsoft.Authorization/roleDefinitions/749f88d5-cbae-40b8-bcfc-e573ddc772fa" + "/providers/Microsoft.Authorization/roleDefinitions/749f88d5-cbae-40b8-bcfc-e573ddc772fa", + "/providers/Microsoft.Authorization/roleDefinitions/17d1049b-9a84-46fb-8f53-869881c3d3ab" ] } } diff --git a/src/resources/Microsoft.Authorization/roleDefinitions/Application-Owners.json b/src/resources/Microsoft.Authorization/roleDefinitions/Application-Owners.json new file mode 100644 index 0000000000..ed16ac22ef --- /dev/null +++ b/src/resources/Microsoft.Authorization/roleDefinitions/Application-Owners.json @@ -0,0 +1,28 @@ +{ + "name": "c9a07a05-a1fc-53fe-a565-5eed25597c03", + "type": "Microsoft.Authorization/roleDefinitions", + "apiVersion": "2022-04-01", + "properties": { + "roleName": "Application-Owners", + "description": "Contributor role granted for application/operations team at resource group level", + "type": "customRole", + "permissions": [ + { + "actions": [ + "*" + ], + "notActions": [ + "Microsoft.Authorization/*/write", + "Microsoft.Network/publicIPAddresses/write", + "Microsoft.Network/virtualNetworks/write", + "Microsoft.KeyVault/locations/deletedVaults/purge/action" + ], + "dataActions": [], + "notDataActions": [] + } + ], + "assignableScopes": [ + "/providers/Microsoft.Management/managementGroups/contoso" + ] + } +} \ No newline at end of file diff --git a/src/resources/Microsoft.Authorization/roleDefinitions/Network-Management.json b/src/resources/Microsoft.Authorization/roleDefinitions/Network-Management.json new file mode 100644 index 0000000000..bcd598b035 --- /dev/null +++ b/src/resources/Microsoft.Authorization/roleDefinitions/Network-Management.json @@ -0,0 +1,26 @@ +{ + "name": "dc726155-3983-5405-b446-9bb27b94e02c", + "type": "Microsoft.Authorization/roleDefinitions", + "apiVersion": "2022-04-01", + "properties": { + "roleName": "Network-Management", + "description": "Platform-wide global connectivity management: virtual networks, UDRs, NSGs, NVAs, VPN, Azure ExpressRoute, and others", + "type": "customRole", + "permissions": [ + { + "actions": [ + "*/read", + "Microsoft.Network/*", + "Microsoft.Resources/deployments/*", + "Microsoft.Support/*" + ], + "notActions": [], + "dataActions": [], + "notDataActions": [] + } + ], + "assignableScopes": [ + "/providers/Microsoft.Management/managementGroups/contoso" + ] + } +} \ No newline at end of file diff --git a/src/resources/Microsoft.Authorization/roleDefinitions/Security-Operations.json b/src/resources/Microsoft.Authorization/roleDefinitions/Security-Operations.json new file mode 100644 index 0000000000..0d2cea8e81 --- /dev/null +++ b/src/resources/Microsoft.Authorization/roleDefinitions/Security-Operations.json @@ -0,0 +1,34 @@ +{ + "name": "d3584a79-4f0d-5980-aa3c-7a76ba783b76", + "type": "Microsoft.Authorization/roleDefinitions", + "apiVersion": "2022-04-01", + "properties": { + "roleName": "Security-Operations", + "description": "Security Administrator role with a horizontal view across the entire Azure estate and the Azure Key Vault purge policy.", + "type": "customRole", + "permissions": [ + { + "actions": [ + "*/read", + "*/register/action", + "Microsoft.KeyVault/locations/deletedVaults/purge/action", + "Microsoft.PolicyInsights/*", + "Microsoft.Authorization/policyAssignments/*", + "Microsoft.Authorization/policyDefinitions/*", + "Microsoft.Authorization/policyExemptions/*", + "Microsoft.Authorization/policySetDefinitions/*", + "Microsoft.Insights/alertRules/*", + "Microsoft.Resources/deployments/*", + "Microsoft.Security/*", + "Microsoft.Support/*" + ], + "notActions": [], + "dataActions": [], + "notDataActions": [] + } + ], + "assignableScopes": [ + "/providers/Microsoft.Management/managementGroups/contoso" + ] + } +} \ No newline at end of file diff --git a/src/resources/Microsoft.Authorization/roleDefinitions/Subscription-Owner.json b/src/resources/Microsoft.Authorization/roleDefinitions/Subscription-Owner.json new file mode 100644 index 0000000000..011caff0fd --- /dev/null +++ b/src/resources/Microsoft.Authorization/roleDefinitions/Subscription-Owner.json @@ -0,0 +1,29 @@ +{ + "name": "402344ce-48c4-5ac1-9320-16726050f964", + "type": "Microsoft.Authorization/roleDefinitions", + "apiVersion": "2022-04-01", + "properties": { + "roleName": "Subscription-Owner", + "description": "Delegated role for subscription owner generated from subscription Owner role", + "type": "customRole", + "permissions": [ + { + "actions": [ + "*" + ], + "notActions": [ + "Microsoft.Authorization/*/write", + "Microsoft.Network/vpnGateways/*", + "Microsoft.Network/expressRouteCircuits/*", + "Microsoft.Network/routeTables/write", + "Microsoft.Network/vpnSites/*" + ], + "dataActions": [], + "notDataActions": [] + } + ], + "assignableScopes": [ + "/providers/Microsoft.Management/managementGroups/contoso" + ] + } +} \ No newline at end of file diff --git a/src/templates/roles.bicep b/src/templates/roles.bicep new file mode 100644 index 0000000000..43949f4699 --- /dev/null +++ b/src/templates/roles.bicep @@ -0,0 +1,43 @@ +targetScope = 'managementGroup' + +// Extract the environment name to dynamically determine which policies to deploy. +var cloudEnv = environment().name + +// The following var contains lists of files containing Role Definition resources to load, grouped by compatibility with Cloud. +var loadRoleDefinitions = { + All: [ + loadJsonContent('../resources/Microsoft.Authorization/roleDefinitions/Application-Owners.json') + loadJsonContent('../resources/Microsoft.Authorization/roleDefinitions/Network-Management.json') + loadJsonContent('../resources/Microsoft.Authorization/roleDefinitions/Security-Operations.json') + loadJsonContent('../resources/Microsoft.Authorization/roleDefinitions/Subscription-Owner.json') + ] + AzureCloud: [] + AzureChinaCloud: [] + AzureUSGovernment: [] +} + +// The following var is used to compile the required Role Definitions into a single object +var roleDefinitionsByCloudType = { + All: loadRoleDefinitions.All + AzureCloud: loadRoleDefinitions.AzureCloud + AzureChinaCloud: loadRoleDefinitions.AzureChinaCloud + AzureUSGovernment: loadRoleDefinitions.AzureUSGovernment +} + +// The following var is used to extract the Role Definitions into a single list for deployment +// This will contain all Role Definitions classified as available for All cloud environments, and those for the current cloud environment +var roleDefinitions = concat(roleDefinitionsByCloudType.All, roleDefinitionsByCloudType[cloudEnv]) + +// Create the Role Definitions as needed for the target cloud environment +resource RoleDefinitions 'Microsoft.Authorization/roleDefinitions@2022-04-01' = [for role in roleDefinitions: { + name: guid(role.properties.roleName, managementGroup().name) + properties: { + roleName: '[${managementGroup().name}] ${role.properties.roleName}' + description: role.properties.description + type: role.properties.type + permissions: role.properties.permissions + assignableScopes: [ + managementGroup().id + ] + } +}]