* Squashed commit of the following:

commit 6d6b3e49855c365f49a4674534b985bacf9cd74c
Author: Barry Willis <bawillis@microsoft.com>
Date:   Mon Feb 27 08:07:45 2023 -0800

    changed the areacode on the logging service health alerts architype

commit 86b4505c2ffd5127978883c0bc6a1f9b0e7d3268
Author: Barry Willis <bawillis@microsoft.com>
Date:   Fri Feb 24 16:39:08 2023 -0800

    prepping for testing in ESLZ test environment

commit 0f92b6bf70aee1377b4d49db436fa7024f1bfd25
Merge: 2a3584a 7749e7b
Author: Barry Willis <bawillis@microsoft.com>
Date:   Fri Feb 24 16:10:37 2023 -0800

    Merge remote-tracking branch 'origin/main' into IdentityLZ

commit 7749e7bf7a
Merge: f6555a4 5337654
Author: Barry Willis <bawillis@microsoft.com>
Date:   Fri Feb 24 16:08:54 2023 -0800

    Merge remote-tracking branch 'github-CanadaPubSecALZ/main'

commit f6555a4122
Author: Barry Willis <bawillis@microsoft.com>
Date:   Mon Feb 13 12:30:20 2023 -0800

    Added the patch version to the AKS versions in the Data Archetypes

commit 8edcb63d83
Author: Barry Willis <bawillis@microsoft.com>
Date:   Mon Feb 13 11:32:54 2023 -0800

    Changed hte AKS version to only have the Major.Minor

commit 37123d7162
Author: Barry Willis <bawillis@microsoft.com>
Date:   Mon Feb 13 11:17:38 2023 -0800

    updated AKS version in the Data Archetypes

commit 459b3c6275
Author: Barry Willis <bawillis@microsoft.com>
Date:   Mon Feb 13 08:55:13 2023 -0800

    changed the servcie health number prefix to 604

commit cccf88662c
Author: Barry Willis <bawillis@microsoft.com>
Date:   Mon Feb 13 07:42:52 2023 -0800

    changed the invalid dummy service alert phone number to a valid phone number

commit 8e9628d26e
Author: Barry Willis <bawillis@microsoft.com>
Date:   Mon Feb 13 07:01:36 2023 -0800

    fixed linter warnings in policy files

commit 6c2b2f7d2d
Author: Barry Willis <bawillis@microsoft.com>
Date:   Sat Feb 11 15:36:36 2023 -0800

    Commit 95556ddd: changed the extensionResourceId function to tenantResourceId for all built-in polify definitions

commit c58ba48f50
Author: Barry Willis <bawillis@microsoft.com>
Date:   Sat Feb 11 15:09:56 2023 -0800

    Fixed the AKS policy deployment

commit f9e8418b7e
Author: Barry Willis <bawillis@microsoft.com>
Date:   Sat Feb 11 14:04:22 2023 -0800

    Fixed Bug on policy defnition

commit 1a3c82e446
Author: Barry Willis <bawillis@microsoft.com>
Date:   Fri Feb 10 19:09:02 2023 -0800

    updated the linter rules

commit 20e188051a
Author: Barry Willis <bawillis@microsoft.com>
Date:   Fri Feb 10 18:52:18 2023 -0800

    fixed the remaining linter errors in the policy definitions

commit 1610a28e35
Author: Barry Willis <bawillis@microsoft.com>
Date:   Fri Feb 10 18:27:14 2023 -0800

    fixed the remaining linter warnings

commit 9f0e049fa0
Author: Barry Willis <bawillis@microsoft.com>
Date:   Fri Feb 10 17:31:21 2023 -0800

    fixed BCP321 warning

commit 466d7b0c07
Author: Barry Willis <bawillis@microsoft.com>
Date:   Fri Feb 10 17:22:46 2023 -0800

    changed the pOlicyScopedId var to be set by using the MGResourceID Function

commit 9362967e50
Author: Barry Willis <bawillis@microsoft.com>
Date:   Fri Feb 10 16:48:26 2023 -0800

    Fixed Role Definition Id References to use the ResourceId function

commit 4bcbc28212
Author: Barry Willis <bawillis@microsoft.com>
Date:   Fri Feb 10 16:07:33 2023 -0800

    Fixed BCP321 Linter warning in networking files

commit 2a3584a7cac9c5822c7a226bc8a5d44f52d69a65
Author: Barry Willis <bawillis@microsoft.com>
Date:   Fri Feb 10 15:07:43 2023 -0800

    Removed Linter exception BCP321 - will fix in the linter PR

commit a0b48ec7710a5ee8023a066e4cb5394074002c1e
Author: Barry Willis <bawillis@microsoft.com>
Date:   Fri Feb 10 10:39:36 2023 -0800

    Fixed the bugs with conditionally deploying DNS Resolver

commit 4f24be78f48465b404c529b276db66496c9958db
Author: Barry Willis <bawillis@microsoft.com>
Date:   Wed Feb 8 15:29:38 2023 -0800

    Updated documentation and made the DNS Resolver subnets optional

commit 03fcb5e50b0670c67d1850063dd828ffa6945cf8
Merge: dfe0d9a 0fa01e8
Author: Barry Willis <bawillis@microsoft.com>
Date:   Mon Feb 6 16:58:41 2023 -0800

    Merge remote-tracking branch 'origin/main' into IdentityLZ

commit dfe0d9acab086df1d9dfbfbdae5770fbf5da999a
Author: Barry Willis <bawillis@microsoft.com>
Date:   Wed Jan 11 15:52:06 2023 -0800

    added Schema validation to the identity config file

commit fb88630b5d707db6b7f4ab1aa2455ff79920d5b3
Author: Barry Willis <bawillis@microsoft.com>
Date:   Mon Jan 9 10:28:13 2023 -0800

    changed the DNS Resolver ruleset to be an object-array

commit 78aaf4d6cdeff8d9832d8a309f26c10cefe97a22
Author: Barry Willis <bawillis@microsoft.com>
Date:   Sat Jan 7 13:57:37 2023 -0800

    first pass at creating conditional forwarding rulesets in the Identity LZ

commit e7b554d04daee83a55a985073ec0c59084c7f3c2
Author: Barry Willis <bawillis@microsoft.com>
Date:   Fri Jan 6 08:54:27 2023 -0800

    Configured Subnet Delegation for Az DNS Resolver

commit 978ab9925f876945ba02280493f7deba1c07e7ee
Author: Barry Willis <bawillis@microsoft.com>
Date:   Thu Jan 5 19:52:24 2023 -0800

    added Private DNS Resolver to the Identity LZ

commit 9735d58fc04d7a587a76a5387deb112c466390fe
Author: Barry Willis <bawillis@microsoft.com>
Date:   Thu Jan 5 13:19:05 2023 -0800

    Removed the optional Subnet

commit 4cd57ed41a09672b3cfbc1792c2edbdc3569a060
Author: Barry Willis <bawillis@microsoft.com>
Date:   Thu Jan 5 13:09:36 2023 -0800

    first cut at the identity LZ framework

commit a119eea02fca28a2028362f484aa2835c9313c1d
Author: Barry Willis <bawillis@microsoft.com>
Date:   Wed Dec 21 11:54:58 2022 -0800

    added identitypathfromroot in the branch config file

commit 75b6ccc2ab6efd55037e0a5a938d49f2eef32de4
Author: Barry Willis <bawillis@microsoft.com>
Date:   Wed Dec 21 11:35:12 2022 -0800

    Added: identity vars display
    Changed: location reference to identity param file

commit e0cfc41b5a83c4c331689fcafa5edc9928e93d39
Author: Barry Willis <bawillis@microsoft.com>
Date:   Wed Dec 21 11:22:35 2022 -0800

    fixed misconfigured working directory

commit fb58b16999aeb9cc6b6b81647c76e95024e1267c
Author: Barry Willis <bawillis@microsoft.com>
Date:   Wed Dec 21 11:18:46 2022 -0800

    removed schema validation to test deployment

commit 240189de7e30fa57654c3ec76ec37c762ff80133
Author: Barry Willis <bawillis@microsoft.com>
Date:   Wed Dec 21 11:15:43 2022 -0800

    fixed bug - neworking region is now identity region

commit 89e63b5976cb5cdc4e85d0b25c01234ffe4853d7
Author: Barry Willis <bawillis@microsoft.com>
Date:   Wed Dec 21 11:11:48 2022 -0800

    initial identity lz deployment

commit d4b40b26b893b78d7a9250dffe24c3e9ce06d690
Author: Barry Willis <bawillis@microsoft.com>
Date:   Wed Dec 21 11:03:29 2022 -0800

    Added default region for Identity Subscription

commit 41e611818d09181b1a455f612425cae20f0683f7
Author: Barry Willis <bawillis@microsoft.com>
Date:   Wed Dec 21 08:29:33 2022 -0800

    Changed bastion subnet range in identity subnet

commit f5a43f2d44803e80db8a043d31e5c9f72fc51675
Author: Barry Willis <bawillis@microsoft.com>
Date:   Wed Dec 21 07:33:03 2022 -0800

    Param file for Identity LZ

commit 13d084b0fe74f39ca1423b2eb9f333a2b760b1f2
Author: Barry Willis <bawillis@microsoft.com>
Date:   Tue Dec 20 15:19:23 2022 +0000

    Deleted identity.parameteres.json

commit 5ba9a12fa8e8e02f60f3f2afea43681cc84d7446
Merge: 002b2be e395307
Author: Barry Willis <bawillis@microsoft.com>
Date:   Tue Dec 20 07:18:40 2022 -0800

    Merge branch 'IdentityLZ' of https://dev.azure.com/Tredell/CanadaALZ/_git/CanadaALZ into IdentityLZ

commit 002b2be1bb5b555a334f35cbb505e7a68f321649
Author: Barry Willis <bawillis@microsoft.com>
Date:   Tue Dec 20 07:18:32 2022 -0800

    id-lz - created param section for id lz

commit e395307b1c12786cc28cf3d4b00586dde69739d5
Author: Barry Willis <bawillis@microsoft.com>
Date:   Tue Dec 20 07:13:54 2022 -0800

    id-lz - created param section for id lz

commit 7f4a43eb4fdc7f6f37ebab8e661981cccbee9f50
Author: Barry Willis <bawillis@microsoft.com>
Date:   Mon Dec 19 14:54:57 2022 -0800

    disabled privatelink infrastructure to be deployed in hub lz

commit db85049ac94b5c394d586b6960343bc1286997f1
Author: Barry Willis <bawillis@microsoft.com>
Date:   Mon Dec 19 14:46:36 2022 -0800

    Configured hub networking parameter files

commit 8d772e868803d1b712013f7db21044d48ab730d2
Author: Barry Willis <bawillis@microsoft.com>
Date:   Mon Dec 19 14:07:43 2022 -0800

    removed comment from json - not supported

commit 89cde8d92704f1a41a123af46da6dd90568d99cb
Author: Barry Willis <bawillis@microsoft.com>
Date:   Mon Dec 19 12:56:47 2022 -0800

    Configuring Policies for deployment to Test enviornment

commit ba781ee844a4abd403071e072645988b63ada494
Author: Barry Willis <bawillis@microsoft.com>
Date:   Mon Dec 19 12:40:53 2022 -0800

    added a default security Group

commit 1269da21e08fdf4c29a53b38a4d18722c64461e0
Author: Barry Willis <bawillis@microsoft.com>
Date:   Mon Dec 19 12:26:14 2022 -0800

    setting up logging for my test environment

commit 4d6a41f4133380223f5895dba270cbce4ae5a39b
Author: Barry Willis <bawillis@microsoft.com>
Date:   Mon Dec 19 12:13:08 2022 -0800

    testing the path to the logging configuraiton file

commit 75d0b99caf6aed5f809c28566cad35569d78be58
Author: Barry Willis <bawillis@microsoft.com>
Date:   Mon Dec 19 12:00:14 2022 -0800

    added the full path to the logging parameters file

commit 32e8382bcb8deaaaab0c7bc1c2791483ef439971
Author: Barry Willis <bawillis@microsoft.com>
Date:   Mon Dec 19 11:55:00 2022 -0800

    path to logging parameters file was incorrect

commit 5757d36a486e7f3b707f00848d19cfe64de83358
Author: Barry Willis <bawillis@microsoft.com>
Date:   Mon Dec 19 11:37:20 2022 -0800

    Changed MG Root to match test enviornment

commit 1fdd02db1638420decf5ab021fb617b95920aada
Author: Barry Willis <bawillis@microsoft.com>
Date:   Mon Dec 19 11:09:46 2022 -0800

    Adding config file for IdentityLZ branch

* PowerShell Deployment Files created

* GitHub Action Pipelines modified to add the Identity Archetype

* made the Identity GitHub Action optional

* put the boolean option in single quotes

* fixed a few bugs (BCP321 & references to the wrong tenant)

* changed the sub id for the logging subscription

* Removed the hardcoded reference to the LAW in the identity param file

* updated the param file with the LAW ID

* disabled private dns zone deployment in the identity sub

* removed the config files from my custom branch

* uncommented the validation in the Identity ADO Pipeline

* removed commented trigger code from ADO Identity Pipeline

* renenabled the dployment of the DNSPrivateEndPoints policyset

* removed the provider registration for containerservices in the deploy-identity-pipeline yaml

* added an explanation comment to the dnsforwardingruleset file

* Added telemetry tracking  for the identity subscription

* fixed cut and paste errors

* Updated test cases & documentation

* added the consistency check & pull request checks for github actions

* fixed spelling error
This commit is contained in:
Barrington Willis 2023-03-03 07:00:06 -08:00 коммит произвёл GitHub
Родитель 533765439f
Коммит f13f6ec24f
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
33 изменённых файлов: 3224 добавлений и 10 удалений

33
.github/workflows/0-everything.yml поставляемый
Просмотреть файл

@ -20,6 +20,11 @@ on:
- "HubNetworkWithNVA"
- "HubNetworkWithAzureFirewall"
default: "HubNetworkWithAzureFirewall"
deployIdentity:
type: boolean
description: "Deploy Identity Subscription"
required: true
default: false
subscriptionIds:
type: string
description: Subscription ID(s) (optional), e.g. "abcd", "1234"
@ -306,6 +311,34 @@ jobs:
-NvaUsername (ConvertTo-SecureString -String '${{secrets.NVA_USERNAME}}' -AsPlainText -Force) `
-NvaPassword (ConvertTo-SecureString -String '${{secrets.NVA_PASSWORD}} '-AsPlainText -Force)
identity:
name: Identity
if: github.event.inputs.deployIdentity == 'true'
needs:
- Logging
- HubNetworking
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Configure PowerShell modules
run: |
Install-Module Az -Force
Install-Module powershell-yaml -Force
- name: Deploy Identity
run: |
./RunWorkflows.ps1 `
-DeployIdentity `
-EnvironmentName '${{github.event.inputs.environmentName}}' `
-LoginServicePrincipalJson (ConvertTo-SecureString -String '${{secrets.ALZ_CREDENTIALS}}' -AsPlainText -Force) `
-GitHubRepo ${env:GITHUB_REPOSITORY} `
-GitHubRef ${env:GITHUB_REF}
SubscriptionMatrix:
if: github.event.inputs.subscriptionIds != ''

46
.github/workflows/6-identity.yml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,46 @@
# ----------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.
#
# THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
# EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
# ----------------------------------------------------------------------------------
name: 6 - Identity
on:
workflow_dispatch:
inputs:
environmentName:
type: string
description: Environment name (optional), e.g. CanadaESLZ-main
required: false
defaults:
run:
shell: pwsh
working-directory: scripts/deployments
jobs:
identity:
name: Identity
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Configure PowerShell modules
run: |
Install-Module Az -Force
Install-Module powershell-yaml -Force
- name: Deploy Identity
run: |
./RunWorkflows.ps1 `
-DeployIdentity `
-EnvironmentName '${{github.event.inputs.environmentName}}' `
-LoginServicePrincipalJson (ConvertTo-SecureString -String '${{secrets.ALZ_CREDENTIALS}}' -AsPlainText -Force) `
-GitHubRepo ${env:GITHUB_REPOSITORY} `
-GitHubRef ${env:GITHUB_REF}

Просмотреть файл

3
.github/workflows/README.md поставляемый
Просмотреть файл

@ -22,7 +22,8 @@ The following workflows are present in the `.github/workflows` repository folder
| 5 | Azure Firewall Policy (required for Hub Networking with Azure Firewall) | `5-azure-firewall-policy.yml`
| 5 | Hub Networking with Azure Firewall | `5-hub-network-with-azure-firewall.yml`
| 5 | Hub Networking with NVA | `5-hub-network-with-nva.yml`
| 6 | Subscriptions | `6-subscriptions.yml`
| 6 | Identity | `6-identity.yml`
| 7 | Subscriptions | `7-subscriptions.yml`
With the exception of the `Everything` workflow, all other workflows need to be run in the order specified. For example, the `Policy` workflow is dependent on resources deployed by the `Logging` workflow. Think of it as a layered approach; once the layer is deployed, it only requires re-running if some configuration at that layer changes.

9
.github/workflows/consistency-check.yml поставляемый
Просмотреть файл

@ -9,6 +9,7 @@ env:
SCHEMA_FOLDER: schemas/latest/landingzones
LOGGING_PATH_FROM_ROOT: config/logging
NETWORKING_PATH_FROM_ROOT: config/networking
IDENTITY_PATH_FROM_ROOT: config/identity
SUBSCRIPTIONS_PATH_FROM_ROOT: config/subscriptions
jobs:
@ -82,6 +83,14 @@ jobs:
Get-Content -Raw $_ | Test-Json -SchemaFile $HubNetworkWithNVASchemaFile
}
$IdentityFileFilter="*.json"
$IdentitySchemaFile="${{env.SCHEMA_FOLDER}}/lz-platform-identity.json"
Get-ChildItem -Recurse -Filter $IdentityFileFilter -Path "${{env.IDENTITY_PATH_FROM_ROOT}}" | ForEach-Object {
Write-Host "Validating: $_ with $IdentitySchemaFile"
Get-Content -Raw $_ | Test-Json -SchemaFile $IdentitySchemaFile
}
$GenericSubscriptionFileFilter="*generic-subscription*.json"
$GenericSubscriptionSchemaFile="${{env.SCHEMA_FOLDER}}/lz-generic-subscription.json"

9
.github/workflows/pull-request-check.yml поставляемый
Просмотреть файл

@ -12,6 +12,7 @@ env:
SCHEMA_FOLDER: schemas/latest/landingzones
LOGGING_PATH_FROM_ROOT: config/logging
NETWORKING_PATH_FROM_ROOT: config/networking
IDENTITY_PATH_FROM_ROOT: config/identity
SUBSCRIPTIONS_PATH_FROM_ROOT: config/subscriptions
jobs:
@ -85,6 +86,14 @@ jobs:
Get-Content -Raw $_ | Test-Json -SchemaFile $HubNetworkWithNVASchemaFile
}
$IdentityFileFilter="*.json"
$IdentitySchemaFile="${{env.SCHEMA_FOLDER}}/lz-platform-identity.json"
Get-ChildItem -Recurse -Filter $IdentityFileFilter -Path "${{env.IDENTITY_PATH_FROM_ROOT}}" | ForEach-Object {
Write-Host "Validating: $_ with $IdentitySchemaFile"
Get-Content -Raw $_ | Test-Json -SchemaFile $IdentitySchemaFile
}
$GenericSubscriptionFileFilter="*generic-subscription*.json"
$GenericSubscriptionSchemaFile="${{env.SCHEMA_FOLDER}}/lz-generic-subscription.json"

Просмотреть файл

@ -0,0 +1,64 @@
# ----------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.
#
# THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
# EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
# ----------------------------------------------------------------------------------
trigger: none
pr: none
variables:
- name: devops-org-name
value: ${{ replace(replace(variables['System.CollectionUri'], 'https://dev.azure.com/' , ''), '/', '') }}
- name: logging-config-directory
value: $(System.DefaultWorkingDirectory)/$(loggingPathFromRoot)/${{ variables['devops-org-name'] }}-${{ variables['Build.SourceBranchName'] }}
- name: identity-config-directory
value: $(System.DefaultWorkingDirectory)/$(identityPathFromRoot)/${{ variables['devops-org-name'] }}-${{ variables['Build.SourceBranchName'] }}
- name: variable-template-file
value: ${{ variables['devops-org-name'] }}-${{ variables['Build.SourceBranchName'] }}.yml
- template: ../config/variables/common.yml
- template: ../config/variables/${{ variables['variable-template-file'] }}
pool:
vmImage: $[ variables.vmImage ]
stages:
- stage: DeployNetworkingStage
displayName: Deploy Networking Stage
jobs:
- deployment: DeployIdentityJob
displayName: Deploy Identity Job
environment: ${{ variables['Build.SourceBranchName'] }}
strategy:
runOnce:
deploy:
steps:
- checkout: self
- template: templates/steps/load-variables.yml
- template: templates/steps/load-log-analytics-vars.yml
parameters:
logAnalyticsSubscriptionId: $(var-logging-subscriptionId)
logAnalyticsConfigurationFile: ${{ variables['logging-config-directory'] }}/$(var-logging-configurationFileName)
- template: templates/steps/show-variables.yml
parameters:
json: ${{ convertToJson(variables) }}
- template: templates/steps/deploy-platform-identity.yml
parameters:
workingDir: $(System.DefaultWorkingDirectory)/landingzones
deployOperation: ${{ variables['deployOperation'] }}
identityManagementGroupId: $(var-identity-managementGroupId)
identitySubscriptionId: $(var-identity-subscriptionId)
identityRegion: $(var-identity-region)
identityConfigurationPath: ${{ variables['identity-config-directory'] }}/$(var-identity-configurationFileName)

Просмотреть файл

@ -96,7 +96,7 @@ stages:
- template: templates/steps/define-policyset.yml
parameters:
description: 'Define Policy Set'
deployTemplates: [AKS, DefenderForCloud, LogAnalytics, Network, DNSPrivateEndpoints, Tags]
deployTemplates: [AKS, DefenderForCloud, DNSPrivateEndpoints, LogAnalytics, Network, Tags]
deployOperation: ${{ variables['deployOperation'] }}
workingDir: $(System.DefaultWorkingDirectory)/policy/custom/definitions/policyset

Просмотреть файл

@ -0,0 +1,83 @@
# ----------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.
#
# THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
# EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
# ----------------------------------------------------------------------------------
parameters:
- name: workingDir
type: string
- name: deployOperation
type: string
default: create
values:
- create
- what-if
- name: identityManagementGroupId
type: string
- name: identitySubscriptionId
type: string
- name: identityRegion
type: string
- name: identityConfigurationPath
type: string
steps:
- task: PowerShell@2
displayName: Validate identity Parameters
inputs:
targetType: 'inline'
script: |
$schemaFile="$(Build.SourcesDirectory)/schemas/latest/landingzones/lz-platform-identity.json"
Write-Host "Parameters File: ${{ parameters.identityConfigurationPath }}"
Write-Host "Schema File: ${schemaFile}"
Get-Content -Raw "${{ parameters.identityConfigurationPath }}" | Test-Json -SchemaFile "${schemaFile}"
- template: ./move-subscription.yml
parameters:
managementGroup: ${{ parameters.identityManagementGroupId }}
subscriptionGuid: ${{ parameters.identitySubscriptionId }}
subscriptionLocation: ${{ parameters.identityRegion }}
templateDirectory: $(Build.SourcesDirectory)/landingzones/utils/mg-move
templateFile: move-subscription.bicep
workingDir: ${{ parameters.workingDir }}/utils/mg-move
- task: AzureCLI@2
displayName: Configure Identity LZ
inputs:
azureSubscription: $(serviceConnection)
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
$(var-bashPreInjectScript)
# Check if the log analytics workspace id is provided in the parameters json.
# If present, then do no change it. Otherwise add it to the json parameter file.
LOG_ANALYTICS_WORKSPACE_RESOURCE_ID_IN_PARAMETERS=`jq -r .parameters.logAnalyticsWorkspaceResourceId.value ${{ parameters.identityConfigurationPath }}`
if [[ $LOG_ANALYTICS_WORKSPACE_RESOURCE_ID_IN_PARAMETERS != null && "$LOG_ANALYTICS_WORKSPACE_RESOURCE_ID_IN_PARAMETERS" != "" ]];
then
echo "Log Analytics Workspace Resource ID is set in ${{ parameters.identityConfigurationPath }} to $LOG_ANALYTICS_WORKSPACE_RESOURCE_ID_IN_PARAMETERS"
else
echo "Log Analytics Workspace Resource ID is not set in ${{ parameters.identityConfigurationPath }}. Updating ${{ parameters.identityConfigurationPath }} with $(var-logging-logAnalyticsWorkspaceResourceId)"
# use jq to update the json parameter file
echo "$( jq '.parameters.logAnalyticsWorkspaceResourceId.value = "$(var-logging-logAnalyticsWorkspaceResourceId)"' ${{ parameters.identityConfigurationPath }} )" > ${{ parameters.identityConfigurationPath }}
fi
echo "Deploying main.bicep using ${{ parameters.deployOperation}} operation using ${{ parameters.identityConfigurationPath }}..."
az deployment sub ${{ parameters.deployOperation }} \
--location ${{ parameters.identityRegion }} \
--subscription ${{ parameters.identitySubscriptionId }} \
--template-file main.bicep \
--parameters @${{ parameters.identityConfigurationPath }}
$(var-bashPostInjectScript)
workingDirectory: '${{ parameters.workingDir }}/lz-platform-identity'

Просмотреть файл

@ -70,4 +70,10 @@ steps:
echo
printenv -0 | grep -zi '^var-hubnetwork-nva-' | xargs -0 -L 1 echo
echo
echo
echo "IDENTITY"
echo
printenv -0 | grep -zi '^var-identity-' | xargs -0 -L 1 echo
$(var-bashPostInjectScript)

Просмотреть файл

@ -0,0 +1,57 @@
// ----------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
// EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
// ----------------------------------------------------------------------------------
param name string
param location string = resourceGroup().location
@description('Outbound endpoint id')
param outEndpointId string
param forwardingRuleSet array
param linkRuleSetToVnet bool = false
param linkName string = ''
param vnetId string = ''
resource ruleset 'Microsoft.Network/dnsForwardingRulesets@2022-07-01' = {
name: name
location: location
properties: {
dnsResolverOutboundEndpoints: [
{
id: outEndpointId
}
]
}
}
resource fwRule 'Microsoft.Network/dnsForwardingRulesets/forwardingRules@2022-07-01' = [for rule in forwardingRuleSet: {
name: rule.name
parent: ruleset
properties: {
forwardingRuleState: rule.state
domainName: endsWith(rule.domain, '.') ? rule.domain : '${rule.domain}.' //Adding a '.' at the end of the domain name if it is not present
targetDnsServers: rule.targetDnsServers
}
}]
module dnsResolverLinkVnet 'dnsresolver-vnet-link.bicep'= if(linkRuleSetToVnet){
name:'deploy-private-dns-resolver-vnet-link'
params:{
forwardingRulesetName: ruleset.name
linkName: linkName
vnetId: vnetId
}
}
output ruleSetName string = ruleset.name

Просмотреть файл

@ -0,0 +1,26 @@
// ----------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
// EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
// ----------------------------------------------------------------------------------
param linkName string
param vnetId string
param forwardingRulesetName string
resource dnsResolver 'Microsoft.Network/dnsForwardingRulesets@2022-07-01' existing = {
name: forwardingRulesetName
}
resource resolverLink 'Microsoft.Network/dnsForwardingRulesets/virtualNetworkLinks@2022-07-01' = {
name: linkName
parent: dnsResolver
properties: {
virtualNetwork: {
id: vnetId
}
}
}

Просмотреть файл

@ -0,0 +1,73 @@
// ----------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
// EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
// ----------------------------------------------------------------------------------
param name string
param location string = resourceGroup().location
param vnetId string
@description('Name of the private dns resolver outbound endpoint')
param inboundEndpointName string
@description('Name of the private dns resolver outbound endpoint')
param outboundEndpointName string
@description('name of the subnet that will be used for private resolver inbound endpoint')
param inboundSubnetName string
@description('name of the subnet that will be used for private resolver outbound endpoint')
param outboundSubnetName string
param vnetResourceGroupName string
param vnetName string
var subscriptionId = subscription().subscriptionId
var inboundSubnetId = resourceId(subscriptionId, vnetResourceGroupName, 'Microsoft.Network/virtualNetworks/subnets', vnetName, inboundSubnetName)
var outboundSubnetId = resourceId(subscriptionId, vnetResourceGroupName, 'Microsoft.Network/virtualNetworks/subnets', vnetName, outboundSubnetName)
resource resolver 'Microsoft.Network/dnsResolvers@2022-07-01' = {
name: name
location: location
properties: {
virtualNetwork: {
id: vnetId
}
}
}
resource inEndPoint 'Microsoft.Network/dnsResolvers/inboundEndpoints@2022-07-01' = {
parent: resolver
name: inboundEndpointName
location: location
properties: {
ipConfigurations: [
{
privateIpAllocationMethod: 'dynamic'
subnet: {
id: inboundSubnetId
}
}
]
}
}
resource outEndpoint 'Microsoft.Network/dnsResolvers/outboundEndpoints@2022-07-01' = {
parent: resolver
name: outboundEndpointName
location: location
properties: {
subnet: {
id: outboundSubnetId
}
}
}
output inboundDnsIp string = inEndPoint.properties.ipConfigurations[0].privateIpAddress
output outboundEndpointId string = outEndpoint.id

Просмотреть файл

@ -0,0 +1,170 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"serviceHealthAlerts": {
"value": {
"resourceGroupName": "service-health",
"incidentTypes": [ "Incident", "Security" ],
"regions": [ "Global", "Canada East", "Canada Central" ],
"receivers": {
"app": [ "alzcanadapubsec@microsoft.com" ],
"email": [ "alzcanadapubsec@microsoft.com" ],
"sms": [ { "countryCode": "1", "phoneNumber": "6045555555" } ],
"voice": [ { "countryCode": "1", "phoneNumber": "6045555555" } ]
},
"actionGroupName": "Service health action group",
"actionGroupShortName": "health-alert",
"alertRuleName": "Incidents and Security",
"alertRuleDescription": "Service Health: Incidents and Security"
}
},
"securityCenter": {
"value": {
"email": "alzcanadapubsec@microsoft.com",
"phone": "6045555555"
}
},
"subscriptionRoleAssignments": {
"value": [
{
"comments": "Built-in Owner Role",
"roleDefinitionId": "8e3af657-a8ff-443c-a75c-2fe8c4bcb635",
"securityGroupObjectIds": [
"3a4fa072-cc14-471d-aeac-49afdbde9f7a"
]
}
]
},
"subscriptionBudget": {
"value": {
"createBudget": false
}
},
"subscriptionTags": {
"value": {
"ISSO": "isso-tbd",
"ClientOrganization": "client-organization-tag",
"CostCenter": "cost-center-tag",
"DataSensitivity": "data-sensitivity-tag",
"ProjectContact": "project-contact-tag",
"ProjectName": "project-name-tag",
"TechnicalContact": "technical-contact-tag"
}
},
"resourceTags": {
"value": {
"ClientOrganization": "client-organization-tag",
"CostCenter": "cost-center-tag",
"DataSensitivity": "data-sensitivity-tag",
"ProjectContact": "project-contact-tag",
"ProjectName": "project-name-tag",
"TechnicalContact": "technical-contact-tag"
}
},
"resourceGroups": {
"value": {
"automation": "automation",
"networking": "networking",
"networkWatcher": "NetworkWatcherRG",
"backupRecoveryVault": "backup",
"domainControllers": "DomainControllersRG",
"dnsResolver": "dns-resolverRG",
"dnsCondionalForwarders": "dns-CondionalForwardersRG",
"privateDnsZones": "pubsec-dns"
}
},
"automation": {
"value": {
"name": "automation"
}
},
"backupRecoveryVault": {
"value": {
"enabled": true,
"name": "backup-vault"
}
},
"privateDnsZones": {
"value": {
"enabled": false,
"resourceGroupName": "pubsec-dns"
}
},
"privateDnsResolver": {
"value": {
"enabled": true,
"name": "dns-resolver",
"inboundEndpointName": "dns-resolver-Inbound",
"outboundEndpointName": "dns-resolver-Outbound"
}
},
"privateDnsResolverRuleset": {
"value": {
"enabled": true,
"name": "dns-resolver-ruleset",
"linkRuleSetToVnet": true,
"linkRuleSetToVnetName": "dns-resolver-vnet-link",
"forwardingRules": [
{
"name": "default",
"domain": "dontMakeMeThink.local",
"state": "Enabled",
"targetDnsServers": [
{
"ipAddress": "10.99.99.100"
},
{
"ipAddress": "10.99.99.99"
}
]
}
]
}
},
"hubNetwork": {
"value": {
"virtualNetworkId": "/subscriptions/ed7f4eed-9010-4227-b115-2a5e37728f27/resourceGroups/pubsec-hub-networking/providers/Microsoft.Network/virtualNetworks/hub-vnet",
"rfc1918IPRange": "10.18.0.0/22",
"rfc6598IPRange": "100.60.0.0/16",
"egressVirtualApplianceIp": "10.18.1.4"
}
},
"network": {
"value": {
"deployVnet": true,
"peerToHubVirtualNetwork": true,
"useRemoteGateway": false,
"name": "id-vnet",
"dnsServers": [
"10.18.1.4"
],
"addressPrefixes": [
"10.15.0.0/24"
],
"subnets": {
"domainControllers": {
"comments": "Identity Subnet for Domain Controllers and VM-Based DNS Servers",
"name": "DomainControllers",
"addressPrefix": "10.15.0.0/27"
},
"dnsResolverInbound": {
"comments": "Azure DNS Resolver Inbound Requests subnet",
"name": "AzureDNSResolver-Inbound",
"addressPrefix": "10.15.0.32/27"
},
"dnsResolverOutbound": {
"comments": "Azure DNS Resolver Outbound Requests subnet",
"name": "AzureDNSResolver-Outbound",
"addressPrefix": "10.15.0.64/27"
},
"optional": []
}
}
}
}
}

Просмотреть файл

@ -10,6 +10,7 @@
"nvaFortinet": "a83f6385-f514-415f-991b-2d9bd7aed658",
"azureFirewall": "a83f6385-f514-415f-991b-2d9bd7aed658"
},
"identity": "a83f6385-f514-415f-991b-2d9bd7aed658",
"archetypes": {
"genericSubscription": "a83f6385-f514-415f-991b-2d9bd7aed658",
"machineLearning": "a83f6385-f514-415f-991b-2d9bd7aed658",

Просмотреть файл

@ -67,6 +67,12 @@ variables:
## This parameter is only used for HIPAA/HITRUST Policy Assignment
var-logging-diagnosticSettingsforNetworkSecurityGroupsStoragePrefix: pubsecnsg
# Platform Identity
var-identity-region: canadacentral
var-identity-managementGroupId: pubsecPlatformIdentity
var-identity-subscriptionId: b357bf7b-3328-4d21-b94b-4bfa84af97b1
var-identity-configurationFileName: identity.parameters.json
# Hub Networking
var-hubnetwork-region: canadacentral
var-hubnetwork-managementGroupId: pubsecPlatformConnectivity

342
docs/archetypes/identity.md Normal file
Просмотреть файл

@ -0,0 +1,342 @@
# Archetype: Generic Subscription
## Table of Contents
- [Archetype: Generic Subscription](#archetype-generic-subscription)
- [Table of Contents](#table-of-contents)
- [Overview](#overview)
- [Azure Deployment](#azure-deployment)
- [Schema Definition](#schema-definition)
- [Delete Locks](#delete-locks)
- [Service Health](#service-health)
- [Deployment Scenarios](#deployment-scenarios)
- [Example Deployment Parameters](#example-deployment-parameters)
- [Recommended Parameter Property Updates](#recommended-parameter-property-updates)
- [Service Health Alerts](#service-health-alerts)
- [Security Center](#security-center)
- [Subscription Role Assignments](#subscription-role-assignments)
- [Resource Tags and Preferred Naming Convention](#resource-tags-and-preferred-naming-convention)
- [Hub Virtual Network ID](#hub-virtual-network-id)
- [Deployment Instructions](#deployment-instructions)
## Overview
Identity and access management are core features of the Azure landing zone implementation. The deployment includes a subscription dedicated to identity, where customers can deploy the Active Directory domain controllers their environments require. This landing zone will be in the `pubsecPlatformIdentity` management group.
![Archetype: Generic Subscription](../media/architecture/archetype-identity.jpg)
**Workflow**
* A new subscription is created through existing process (either via ea.azure.com or Azure Portal).
* The subscription will automatically be assigned to the **pubsecSandbox** management group.
* Update configuration in Azure DevOps Git repo
* Execute the Platofrm - Identity azure DevOps Pipeline. The pipeline will:
* Move it to the target management group
* Scaffold the subscription with baseline configuration.
**Subscription Move**
Subscription can be moved to a target Management Group through Azure ARM Templates/Bicep. Move has been incorporated into the landing zone Azure DevOps Pipeline automation.
**Capabilities**
| Capability | Description |
| --- | --- |
| Service Health Alerts | Configures Service Health alerts such as Security, Incident, Maintenance. Alerts are configured with email, sms and voice notifications. |
| Microsoft Defender for Cloud | Configures security contact information (email and phone). |
| Subscription Role Assignments | Configures subscription scoped role assignments. Roles can be built-in or custom. |
| Subscription Budget | Configures monthly subscription budget with email notification. Budget is configured by default for 10 years and the amount. |
| Subscription Tags | A set of tags that are assigned to the subscription. |
| Resource Tags | A set of tags that are assigned to the resource group and resources. These tags must include all required tags as defined the Tag Governance policy. |
| Automation | Deploys an Azure Automation Account in each subscription. |
| Backup Recovery Vault | Configures a backup recovery vault . |
| Hub Networking | Configures virtual network peering to Hub Network which is required for egress traffic flow and hub-managed DNS resolution (on-premises or other spokes, private endpoints).
| Networking | A spoke virtual network with 1 to 3 subnets: Domain Controllers, DNS Resolver Inbound, DNS Resolver Outbound. Additional subnets can be configured at deployment time using configuration (see below).
| DNS Resolver | Configures DNS Resolver with inbound and outbound forwarding. Inbound forwarding is configured to forward DNS queries to the Hub Network DNS Resolver. Outbound forwarding is configured to forward DNS queries to the Hub Network DNS Resolver. |
| DNS Forwarding Ruleset | Configures DNS Forwarding Ruleset to forward DNS queries to the Hub Network DNS Resolver.
| Private DNS Zones | Optionally configures the PrivateLink DNS zones to be linked to the Identity vNET
## Azure Deployment
### Schema Definition
Reference implementation uses parameter files with `object` parameters to consolidate parameters based on their context. The schemas types are:
* Schema (version: `latest`)
* [Identity deployment parameters definition](../../schemas/latest/landingzones/lz-platform-identity.json)
* Common types
* [Location](../../schemas/latest/landingzones/types/location.json)
* [Service Health Alerts](../../schemas/latest/landingzones/types/serviceHealthAlerts.json)
* [Microsoft Defender for Cloud](../../schemas/latest/landingzones/types/securityCenter.json)
* [Subscription Role Assignments](../../schemas/latest/landingzones/types/subscriptionRoleAssignments.json)
* [Subscription Budget](../../schemas/latest/landingzones/types/subscriptionBudget.json)
* [Subscription Tags](../../schemas/latest/landingzones/types/subscriptionTags.json)
* [Resource Tags](../../schemas/latest/landingzones/types/resourceTags.json)
* [Log Analytics Workspace](../../schemas/latest/landingzones/types/logAnalyticsWorkspaceId.json)
* [Automation](../../schemas/latest/landingzones/types/automation.json)
* [Backup Recovery Vault](../../schemas/latest/landingzones/types/backupRecoveryVault.json)
### Service Health
[Service health notifications](https://learn.microsoft.com/azure/service-health/service-health-notifications-properties) are published by Azure, and contain information about the resources under your subscription. Service health notifications can be informational or actionable, depending on the category.
Our examples configure service health alerts for `Security` and `Incident`. However, these categories can be customized based on your need. Please review the possible options in [Azure Docs](https://learn.microsoft.com/azure/service-health/service-health-notifications-properties#details-on-service-health-level-information).
### Deployment Scenarios
> Sample deployment scenarios are based on the latest JSON parameters file schema definition. If you have an older version of this repository, please use the examples from your repository.
| Scenario | Example JSON Parameters | Notes |
|:-------- |:----------------------- |:----- |
| Deployment with DNS Resolver | [tests/schemas/lz-platform-identity/lz-Identity-With-DNS-Resolver.json](../../tests/schemas/lz-platform-identity/lz-Identity-With-DNS-Resolver.json) | Does not deploy Private DNS Zones |
| Deployment without DNS Resolver| [tests/schemas/lz-platform-identity/lz-Identity-Without-DNS-Resolver.json](../../tests/schemas/lz-platform-identity/lz-Identity-Without-DNS-Resolver.json) | `parameters.privateDnsResolver.value.enabled` is `false`. If this setting is false the DNS Conditional Setting ruleset will not be deployed even if it's set to true |
| Deployment with DNS Resolver and Private DNS Zones | [tests/schemas/lz-platform-identity/lz-Identity-With-Private-DNS-Zones-And-DNS-Resolver.json](../../tests/schemas/lz-platform-identity/lz-Identity-With-Private-DNS-Zones-And-DNS-Resolver.json) | `parameters.privatednszones.value.enabled` is set to `true` && `parameters.privateDnsResolver.value.enabled` is `true` |
| Deployment with Private DNS Zones | [tests/schemas/lz-platform-identity/lz-Identity-With-Private-DNS-Zones.json](../../tests/schemas/lz-platform-identity/lz-Identity-With-Private-DNS-Zones.json) | `parameters.privatednszones.value.enabled` is set to `true`.|
### Example Deployment Parameters
This example configures:
1. Service Health Alerts
2. Microsoft Defender for Cloud
3. Subscription Role Assignments using built-in and custom roles
4. Subscription Budget with $1000
5. Subscription Tags
6. Resource Tags (aligned to the default tags defined in [Policies](../../policy/custom/definitions/policyset/Tags.parameters.json))
7. Log Analytics Workspace integration through Azure Defender for Cloud
8. Automation Account
9. Backup Recovery Vault
10. Spoke Virtual Network with Hub-managed DNS, Virtual Network Peering and 3 subnets.
```json
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"logAnalyticsWorkspaceResourceId": {
"value": "/subscriptions/46e3c98c-7c51-4634-be53-df9916714a46/resourceGroups/pubsec-central-logging/providers/Microsoft.OperationalInsights/workspaces/bwill-log-analytics-workspace"
},
"serviceHealthAlerts": {
"value": {
"resourceGroupName": "service-health",
"incidentTypes": [ "Incident", "Security" ],
"regions": [ "Global", "Canada East", "Canada Central" ],
"receivers": {
"app": [ "alzcanadapubsec@microsoft.com" ],
"email": [ "alzcanadapubsec@microsoft.com" ],
"sms": [ { "countryCode": "1", "phoneNumber": "5555555555" } ],
"voice": [ { "countryCode": "1", "phoneNumber": "5555555555" } ]
},
"actionGroupName": "Service health action group",
"actionGroupShortName": "health-alert",
"alertRuleName": "Incidents and Security",
"alertRuleDescription": "Service Health: Incidents and Security"
}
},
"securityCenter": {
"value": {
"email": "alzcanadapubsec@microsoft.com",
"phone": "5555555555"
}
},
"subscriptionRoleAssignments": {
"value": [
{
"comments": "Built-in Owner Role",
"roleDefinitionId": "8e3af657-a8ff-443c-a75c-2fe8c4bcb635",
"securityGroupObjectIds": [
"3af30d9f-04aa-4d64-b4d5-407d7ff64ff8"
]
}
]
},
"subscriptionBudget": {
"value": {
"createBudget": false
}
},
"subscriptionTags": {
"value": {
"ISSO": "isso-tbd",
"ClientOrganization": "client-organization-tag",
"CostCenter": "cost-center-tag",
"DataSensitivity": "data-sensitivity-tag",
"ProjectContact": "project-contact-tag",
"ProjectName": "project-name-tag",
"TechnicalContact": "technical-contact-tag"
}
},
"resourceTags": {
"value": {
"ClientOrganization": "client-organization-tag",
"CostCenter": "cost-center-tag",
"DataSensitivity": "data-sensitivity-tag",
"ProjectContact": "project-contact-tag",
"ProjectName": "project-name-tag",
"TechnicalContact": "technical-contact-tag"
}
},
"resourceGroups": {
"value": {
"automation": "automation",
"networking": "networking",
"networkWatcher": "NetworkWatcherRG",
"backupRecoveryVault": "backup",
"domainControllers": "DomainControllersRG",
"dnsResolver": "dns-resolverRG",
"dnsCondionalForwarders": "dns-CondionalForwardersRG",
"privateDnsZones": "pubsec-dns"
}
},
"automation": {
"value": {
"name": "automation"
}
},
"backupRecoveryVault": {
"value": {
"enabled": true,
"name": "backup-vault"
}
},
"privateDnsZones": {
"value": {
"enabled": false,
"resourceGroupName": "pubsec-dns"
}
},
"privateDnsResolver": {
"value": {
"enabled": true,
"name": "dns-resolver",
"inboundEndpointName": "dns-resolver-Inbound",
"outboundEndpointName": "dns-resolver-Outbound"
}
},
"privateDnsResolverRuleset": {
"value": {
"enabled": true,
"name": "dns-resolver-ruleset",
"linkRuleSetToVnet": true,
"linkRuleSetToVnetName": "dns-resolver-vnet-link",
"forwardingRules": [
{
"name": "default",
"domain": "dontMakeMeThink.local",
"state": "Enabled",
"targetDnsServers": [
{
"ipAddress": "10.99.99.100"
},
{
"ipAddress": "10.99.99.99"
}
]
}
]
}
},
"hubNetwork": {
"value": {
"virtualNetworkId": "/subscriptions/db8a3c31-7dbb-4368-8883-f9e6333ff23a/resourceGroups/pubsec-hub-networking/providers/Microsoft.Network/virtualNetworks/hub-vnet",
"rfc1918IPRange": "10.18.0.0/22",
"rfc6598IPRange": "100.60.0.0/16",
"egressVirtualApplianceIp": "10.18.1.4"
}
},
"network": {
"value": {
"deployVnet": true,
"peerToHubVirtualNetwork": true,
"useRemoteGateway": false,
"name": "id-vnet",
"dnsServers": [
"10.18.1.4"
],
"addressPrefixes": [
"10.15.0.0/24"
],
"subnets": {
"domainControllers": {
"comments": "Identity Subnet for Domain Controllers and VM-Based DNS Servers",
"name": "DomainControllers",
"addressPrefix": "10.15.0.0/27"
},
"dnsResolverInbound": {
"comments": "Azure DNS Resolver Inbound Requests subnet",
"name": "AzureDNSResolver-Inbound",
"addressPrefix": "10.15.0.32/27"
},
"dnsResolverOutbound": {
"comments": "Azure DNS Resolver Outbound Requests subnet",
"name": "AzureDNSResolver-Outbound",
"addressPrefix": "10.15.0.64/27"
},
"optional": []
}
}
}
}
}
```
## Recommended Parameter Property Updates
### Service Health Alerts
Update the **serviceHealthAlerts** properties with specific email addresses and phone numbers as required.
![Generic Subscription: Service Health Alerts](../../docs/media/archetypes/service-health-alerts-receivers.jpg)
### Security Center
Change the **securityCenter** properties with specific email and address values to reflect your actual point of contact.
![Generic Subscription: Security Center](../../docs/media/archetypes/security-center-contact-info.jpg)
### Subscription Role Assignments
Modify the two **subscriptionRoleAssignments** properties with your specific unique object ids of the respective groups for the **Contributor** built-in
and **Custom Role: Landing Zone Application Owner** roles for this landing zone subscription. These assignments are optional and can be 0 or more role assignments using either Built-In or Custom roles and security groups.
![Generic Subscription: Subscription Role Assignments](../../docs/media/archetypes/subscription-role-assignments.jpg)
### Resource Tags and Preferred Naming Convention
1. Specify the desired custom values for the **resourceTags** properties.
You may also include any additional name value pairs of tags required. Generally, these tags can be modified and even replaced as required, and should also align to the Tagging policy set paramters at: [Tag Policy](https://github.com/Azure/CanadaPubSecALZ/blob/main/policy/custom/definitions/policyset/Tags.parameters.json).
2. Addtionally, you can customize default resources and resource group names with any specific preferred naming convention, as indicated by the item **2** circles shown below.
![Generic Subscription: Tags and Naming Conventions](../../docs/media/archetypes/resource-tags-and-naming-conventions.jpg)
### Hub Virtual Network ID
**IMPORTANT**
To avoid a failure when running any of the connectivity pipelines, the subscriptionId segment value of the **hubNetwork** string (item **1**), must be updated from it's default value to the specific hubNetwork subscriptionId that was actually deployed previously, so that the virtual network in this spoke subscription can be VNET Peered to the Hub Network.
![Generic Subscription: Hub Virtual Network ID](../../docs/media/archetypes/virtual-network-id.jpg)
The rest of the segments for the **virtualNetworkId** string must also match the actual resources that were deployed from the connectivity pipeline, such as the name of the resource group,
in case a different prefix besides **pubsec** was used to conform to a specific and preferred naming convention or organization prefix (item **2**), or the default VNET name of hub-vnet was also changed to something else,
(**item 3**) - again based on a specific and preferred naming convention that may have been used before when the actual hub VNET was deployed.
### Deployment Instructions
### Virtual Appliance IP
To ensure traffic is routed/filtered via the firewall, please validate or update the "egressVirtualApplianceIp" value to the firewall IP in your environment:
- For Azure Firewall, use the firewall IP address
- For Network Virtual Appliances (i.e. Fortigate firewalls), use the internal load-balancer IP (item **1**)
![Generic Subscription:Egress Virtual Appliance IP](../../docs/media/archetypes/egressvirtualApplianceIP.jpg)
Please see [archetype authoring guide for deployment instructions](authoring-guide.md#deployment-instructions).

Просмотреть файл

@ -293,19 +293,28 @@ Azure PaaS services use Private DNS Zones to map their fully qualified domain na
* Private DNS Zones from being created in the spoke subscriptions. These can only be created in the designated resource group in the Hub Subscription.
* Ensure private endpoints can be automatically mapped to the centrally managed Private DNS Zones.
The following diagram shows a typical high-level architecture for enterprise environments with central DNS resolution and name resolution for Private Link resources via Azure Private DNS. This topology provides:
The following diagrams show a typical high-level architecture for enterprise environments with central DNS resolution and name resolution for Private Link resources via Azure Private DNS. This topology provides:
* Name resolution from hub to spoke
* Name resolution from spoke to spoke
* Name resolution from on-premises to Azure (Hub & Spoke resources). Additional configuration is required to deploy DNS resolvers in the Hub Network & provide DNS forwarding from on-premises to Azure.
**`DNS Resolution using Azure DNS Resolver`**
![DNS using Azure DNS Resolver](https://learn.microsoft.com/en-us/azure/dns/media/dns-resolver-overview/resolver-architecture.png)
**Reference:** [What is Azure DNS Private Resolver?](https://learn.microsoft.com/en-us/azure/dns/dns-resolver-overview)
**`DNS using Virtual Machines managed by IT`**
![Hub Managed DNS](media/architecture/hubnetwork-private-link-central-dns.png)
**Reference:** [Private Link and DNS integration at scale](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/private-link-and-dns-integration-at-scale)
Reference implementation provides the following capabilities:
* Deploy Private DNS Zones to the Hub Networking subscription. Enable/disable via configuration.
* Deploy Private DNS Zones to the Hub Networking or Identity subscription. Enable/disable via configuration.
* Deploy Azure DNS Private Resolver to the Hub or Identity Subscription. Enable/disable via configuration.
* Azure Policy to block private zones from being created outside of the designated resource group in the Hub networking subscription.
* Azure Policy to automatically detect new private endpoints and add their A records to their respective Private DNS Zone.
* Support to ensure Hub managed Private DNS Zones are used when deploying archetypes.
@ -316,7 +325,7 @@ The reference implementation does not deploy DNS Servers (as Virtual Machines) i
* Link Private DNS Zones directly to the spoke virtual networks and use the [built-in DNS resolver in each virtual network](https://learn.microsoft.com/azure/virtual-network/virtual-networks-name-resolution-for-vms-and-role-instances). Virtual network(s) in spoke subscriptions be configured through Virtual Network Link for name resolution. DNS resolution is automatic once the Private DNS Zone is linked to the virtual network.
* Leverage DNS Servers on virtual machines that are managed by department's IT.
* Leverage DNS Services from either Azure DNS Private Resolver or on virtual machines that are managed by department's IT.
### Spoke Landing Zone Networks
@ -556,6 +565,7 @@ Use the [Azure DevOps Pipelines](onboarding/azure-devops-pipelines.md) onboardin
| Platform – Hub Networking using NVAs | platform-connectivity-hub-nva.yml | platform-connectivity-hub-nva-ci | Configures Hub Networking with Fortigate Firewalls. | spn-azure-platform-ops | None |
| Platform – Hub Networking with Azure Firewall - Firewall Policy | platform-connectivity-hub-azfw-policy.yml | platform-connectivity-hub-azfw-policy-ci | Configures Azure Firewall Policy. A policy contains firewall rules and firewall configuration such as enabling DNS Proxy. Firewall policies can be updated independently of Azure Firewall. | spn-azure-platform-ops | None |
| Platform – Hub Networking with Azure Firewall | platform-connectivity-hub-azfw.yml | platform-connectivity-hub-azfw-ci | Configures Hub Networking with Azure Firewall. | spn-azure-platform-ops | None |
| Identity | platform-identity.yml | platform-identity-ci | Configures a Identity Landing Zone that will be used by all landing zones for managing identities services (i.e. Domain Controllers). | spn-azure-platform-ops | None |
| Subscriptions | subscriptions.yml | subscriptions-ci | Configures a new subscription based on the archetype defined in the configuration file name. | spn-azure-platform-ops | None |
| Pull Request Validation | pull-request-check.yml | pull-request-validation-ci | Checks for breaking changes to Bicep templates & parameter schemas prior to merging the change to main branch. This pipeline must be configured as a check for the `main` branch. | spn-azure-platform-ops | None |

Двоичные данные
docs/media/architecture/archetype-identity.jpg Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 138 KiB

Просмотреть файл

@ -63,6 +63,7 @@ This deployment diagram describes the steps for deploying one, many or all modul
Logging: Logging
Policy: Azure Policy
HubNetworking: Hub Networking (NVAs or Azure Firewall)
Identity: Identity
Archetypes: Archetypes (Spokes)
[*] --> ManagementGroups
@ -73,10 +74,13 @@ This deployment diagram describes the steps for deploying one, many or all modul
Policy --> HubNetworking
Policy --> Archetypes
HubNetworking --> Identity
HubNetworking --> Archetypes
Policy --> [*]
Identity --> [*]
HubNetworking --> [*]
Archetypes --> [*]
```
@ -103,6 +107,10 @@ This deployment diagram describes the steps for deploying one, many or all modul
AssignDDOSPolicy: [Optional] Assign Azure Policy for linking DDoS Standard Plan to virtual network
AssignPrivateDNSZonesPolicy: [Optional] Assign Azure Policies for centrally managing private DNS zones
Identity: Identity
DeployVirtualNetwork: Deploy Virtual Network
DeployDNSResolver: Deploy DNS Resolver (optional)
Archetypes: Archetypes (Spokes)
DeployGenericSubscriptionArchetype: Generic Subscription
DeployMachineLearningArchetype: Machine Learning
@ -126,6 +134,7 @@ This deployment diagram describes the steps for deploying one, many or all modul
}
Policy --> HubNetworking: When Hub Networking is required
HubNetworking --> Archetypes: When archetypes are deployed in spoke subscriptions
Policy --> Archetypes: When existing Hub Networking is in place
state HubNetworking {
@ -150,7 +159,13 @@ This deployment diagram describes the steps for deploying one, many or all modul
AssignPrivateDNSZonesPolicy --> [*]
}
HubNetworking --> Archetypes: When archetypes are deployed in spoke subscriptions
HubNetworking --> Identity: When Identity Sub is required
state Identity {
DeployVirtualNetwork --> DeployDNSResolver
DeployDNSResolver --> [*]
}
state Archetypes {
state ArchetypeChoice <<choice>>
@ -163,7 +178,8 @@ This deployment diagram describes the steps for deploying one, many or all modul
}
Policy --> [*]: MVP deployment and enables Microsoft Sentinel & Log Analytics
HubNetworking --> [*]
HubNetworking --> [*]: Identity Sub is NOT required
Identity --> [*]
Archetypes --> [*]
```
@ -178,7 +194,8 @@ This deployment diagram describes the steps for deploying one, many or all modul
* [Step 5 - Configure Logging](#step-5---configure-logging)
* [Step 6 - Configure Azure Policies](#step-6---configure-azure-policies)
* [Step 7 - Configure Hub Networking](#step-7---configure-hub-networking)
* [Step 8 - Configure Subscription Archetypes](#step-8---configure-subscription-archetypes)
* [Step 8 - Configure Identity subscription](#step-8---configure-identity-subscription)
* [Step 9 - Configure Subscription Archetypes](#step-9---configure-subscription-archetypes)
* [Appendix](#appendix)
* [Populate management group hierarchy from your environment](#populate-management-group-hierarchy-from-your-environment)
* [Migrate Logging configuration from Azure DevOps variables to JSON parameters file](#migrate-logging-configuration-from-azure-devops-variables-to-json-parameters-file)
@ -1479,8 +1496,168 @@ In order to configure audit stream for Azure Monitor, identify the following inf
* When using Hub Networking with Azure Firewall, run `platform-connectivity-hub-azfw-policy-ci` pipeline first. This ensures that the Azure Firewall Policy is deployed and can be used as a reference for Azure Firewall. This approach allows for Azure Firewall Policies (such as allow/deny rules) to be managed independently from the Hub Networking components.
---
## Step 8 - Configure Identity Subscription
## Step 8 - Configure Subscription Archetypes
1. Configure Pipeline definition for Identity
> Pipelines are stored as YAML definitions in Git and imported into Azure DevOps Pipelines. This approach allows for portability and change tracking.
1. Go to Pipelines
1. New Pipeline
1. Choose Azure Repos Git
1. Select Repository
1. Select Existing Azure Pipeline YAML file
1. Identify the pipeline in `.pipelines/platform-identity.yml`.
1. Save the pipeline (don't run it yet)
1. Rename the pipeline to `identity-ci`
1. Create a subscription configuration file (JSON)
1. Create directory ./config/identity.
1. Create subdirectory based on the syntax: `<devops-org-name>-<branch-name>` (i.e. `CanadaESLZ-main` to create path `./config/identity/CanadaESLZ-main/`).
1. Make a copy of an existing subscription configuration file under `config/identity/CanadaESLZ-main` as a starting point
1. Define deployment parameters based on example below.
* Set the values for the Azure tags that would be applied to the identity subscription and the Identity resources.
* Set resource group names for the Identity resources.
> **Note:** Each resource group is created if the associated resource's Enabled flag is set to `true`.
* Example deployment parameters file:
```json
"subscriptionTags": {
"value": {
"ISSO": "isso-tbd",
"ClientOrganization": "client-organization-tag",
"CostCenter": "cost-center-tag",
"DataSensitivity": "data-sensitivity-tag",
"ProjectContact": "project-contact-tag",
"ProjectName": "project-name-tag",
"TechnicalContact": "technical-contact-tag"
}
},
"resourceTags": {
"value": {
"ClientOrganization": "client-organization-tag",
"CostCenter": "cost-center-tag",
"DataSensitivity": "data-sensitivity-tag",
"ProjectContact": "project-contact-tag",
"ProjectName": "project-name-tag",
"TechnicalContact": "technical-contact-tag"
}
},
"resourceGroups": {
"value": {
"automation": "automation",
"networking": "networking",
"networkWatcher": "NetworkWatcherRG",
"backupRecoveryVault": "backup",
"domainControllers": "DomainControllersRG",
"dnsResolver": "dns-resolverRG",
"dnsCondionalForwarders": "dns-CondionalForwardersRG",
"privateDnsZones": "pubsec-dns"
}
},
```
* Configure Azure DNS Private Resolver
```json
"privateDnsResolver": {
"value": {
"enabled": true,
"name": "dns-resolver",
"inboundEndpointName": "dns-resolver-Inbound",
"outboundEndpointName": "dns-resolver-Outbound"
}
},
"privateDnsResolverRuleset": {
"value": {
"enabled": true,
"name": "dns-resolver-ruleset",
"linkRuleSetToVnet": true,
"linkRuleSetToVnetName": "dns-resolver-vnet-link",
"forwardingRules": [
{
"name": "default",
"domain": "dontMakeMeThink.local",
"state": "Enabled",
"targetDnsServers": [
{
"ipAddress": "10.99.99.100"
},
{
"ipAddress": "10.99.99.99"
}
]
}
]
}
},
```
* Configure the Identity network & it's peering connection to the hub network
> **Note:** If the PrivateDnsResolver Enabled setting is set to `false` the associated DNS Resolver subnets will not be deployed.
```json
"hubNetwork": {
"value": {
"virtualNetworkId": "/subscriptions/db8a3c31-7dbb-4368-8883-f9e6333ff23a/resourceGroups/pubsec-hub-networking/providers/Microsoft.Network/virtualNetworks/hub-vnet",
"rfc1918IPRange": "10.18.0.0/22",
"rfc6598IPRange": "100.60.0.0/16",
"egressVirtualApplianceIp": "10.18.1.4"
}
},
"network": {
"value": {
"deployVnet": true,
"peerToHubVirtualNetwork": true,
"useRemoteGateway": false,
"name": "id-vnet",
"dnsServers": [
"10.18.1.4"
],
"addressPrefixes": [
"10.15.0.0/24"
],
"subnets": {
"domainControllers": {
"comments": "Identity Subnet for Domain Controllers and VM-Based DNS Servers",
"name": "DomainControllers",
"addressPrefix": "10.15.0.0/27"
},
"dnsResolverInbound": {
"comments": "Azure DNS Resolver Inbound Requests subnet",
"name": "AzureDNSResolver-Inbound",
"addressPrefix": "10.15.0.32/27"
},
"dnsResolverOutbound": {
"comments": "Azure DNS Resolver Outbound Requests subnet",
"name": "AzureDNSResolver-Outbound",
"addressPrefix": "10.15.0.64/27"
},
"optional": []
}
}
}
```
1. Configure the Azure DevOps pipeline for Identity
1. In Azrue DevOps, go to Pipelines
1. New Pipeline
1. Select Existing Azrue Pipline YAML file
1. Identify the pipeline in `.pipelines/identity.yml`
1. save the pipeline (don't run it yet)
1. Rename the pipeline to `identity-ci`
1. Run pipeline and wait for completion
---
## Step 9 - Configure Subscription Archetypes
1. Configure Pipeline definition for subscription archetypes

Просмотреть файл

@ -260,6 +260,7 @@ Run the `create-pipelines.bat` script to create the landing zone pipelines:
- platform-connectivity-hub-nva-ci
- platform-connectivity-hub-azfw-ci
- platform-connectivity-hub-azfw-policy-ci
- platform-identity-ci
- subscriptions-ci
If you would rather perform these steps manually, detailed guidance is available in the following sections of the [Azure DevOps Pipelines Onboarding Guide](./azure-devops-pipelines.md):
@ -269,7 +270,8 @@ If you would rather perform these steps manually, detailed guidance is available
- [Step 5 - Configure Logging](./azure-devops-pipelines.md#step-5--configure-logging)
- [Step 6 - Configure Azure Policies](./azure-devops-pipelines.md#step-6---configure-azure-policies)
- [Step 7 - Configure Hub Networking](./azure-devops-pipelines.md#step-7---configure-hub-networking)
- [Step 8 - Configure Subscription Archetypes](./azure-devops-pipelines.md#step-8---configure-subscription-archetypes)
- [Step 8 - Configure Identity Subscription](./azure-devops-pipelines.md#step-8---configure-identity-subscription)
- [Step 9 - Configure Subscription Archetypes](./azure-devops-pipelines.md#step-9---configure-subscription-archetypes)
### Give pipelines access to service endpoint

Просмотреть файл

@ -0,0 +1,112 @@
// ----------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
// EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
// ----------------------------------------------------------------------------------
targetScope = 'subscription'
@description('Location for the deployment.')
param location string = deployment().location
// Example (JSON)
// -----------------------------
// "resourceTags": {
// "value": {
// "ClientOrganization": "client-organization-tag",
// "CostCenter": "cost-center-tag",
// "DataSensitivity": "data-sensitivity-tag",
// "ProjectContact": "project-contact-tag",
// "ProjectName": "project-name-tag",
// "TechnicalContact": "technical-contact-tag"
// }
// }
// Example (Bicep)
// -----------------------------
// {
// ClientOrganization: 'client-organization-tag'
// CostCenter: 'cost-center-tag'
// DataSensitivity: 'data-sensitivity-tag'
// ProjectContact: 'project-contact-tag'
// ProjectName: 'project-name-tag'
// TechnicalContact: 'technical-contact-tag'
// }
@description('A set of key/value pairs of tags assigned to the resource group and resources.')
param resourceTags object
@description('Network configuration for the spoke virtual network. It includes name, dnsServers, address spaces, vnet peering and subnets.')
param network object
// Private DNS Resolver
@description('Private DNS Resolver configuration for Inbound connections.')
param privateDnsResolver object
// Private DNS Resolver Ruleset
@description('Private DNS Resolver Default Ruleset Configuration')
param privateDnsResolverRuleset object
// Private DNS Resolver Ruleset
@description('Private DNS Resolver Default Ruleset Configuration')
param dnsResolverRG string
// vnet resource group
@description('virtual network resource group name')
param rgVnet string
// vnet
@description('virtual network ID')
param vnetId string
// vnet
@description('virtual network Name')
param vnetName string
// Create Private DNS Resolver Resource Group
resource rgPrivateDnsResolver 'Microsoft.Resources/resourceGroups@2020-06-01' = {
name: dnsResolverRG
location: location
tags: resourceTags
}
//create Private DNS Resolver
module dnsResolver '../../azresources/network/dnsresolver.bicep' ={
name:'deploy-private-dns-resolver'
scope: rgPrivateDnsResolver
params:{
name: privateDnsResolver.name
location: location
inboundEndpointName: privateDnsResolver.inboundEndpointName
inboundSubnetName: network.subnets.dnsResolverInbound.name
outboundEndpointName: privateDnsResolver.outboundEndpointName
outboundSubnetName: network.subnets.dnsResolverOutbound.name
vnetResourceGroupName: rgVnet
vnetId: vnetId
vnetName: vnetName
}
}
module dnsResolverFwRuleset '../../azresources/network/dns-forwarding-ruleset.bicep' = if (privateDnsResolverRuleset.enabled) {
name:'deploy-private-dns-resolver-fw-ruleset'
scope: rgPrivateDnsResolver
params:{
name: privateDnsResolverRuleset.name
location: location
outEndpointId: dnsResolver.outputs.outboundEndpointId
forwardingRuleSet: privateDnsResolverRuleset.forwardingRules
linkRuleSetToVnet: privateDnsResolverRuleset.linkRuleSetToVnet
linkName: privateDnsResolverRuleset.linkRuleSetToVnetName
vnetId: vnetId
}
}

Просмотреть файл

@ -0,0 +1,340 @@
// ----------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
// EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
// ----------------------------------------------------------------------------------
/*
Identity Landing Zone to support ESLZ topology. This architeype will provide:
* Azure Automation Account
* Azure Virtual Network
* Azure Recovery Services Vault
* Role-based access control for Owner, Contributor & Reader
* Integration with Azure Cost Management for Subscription-scoped budget
* Integration with Microsoft Defender for Cloud
* Azure Private DNS Resolver & Conditional Forwarder Zone (optional).
* Enables Azure Private DNS Zones (optional).
*/
targetScope = 'subscription'
@description('Location for the deployment.')
param location string = deployment().location
// Service Health
// Example (JSON)
// -----------------------------
// "serviceHealthAlerts": {
// "value": {
// "incidentTypes": [ "Incident", "Security", "Maintenance", "Information", "ActionRequired" ],
// "regions": [ "Global", "Canada East", "Canada Central" ],
// "receivers": {
// "app": [ "email-1@company.com", "email-2@company.com" ],
// "email": [ "email-1@company.com", "email-3@company.com", "email-4@company.com" ],
// "sms": [ { "countryCode": "1", "phoneNumber": "1234567890" }, { "countryCode": "1", "phoneNumber": "0987654321" } ],
// "voice": [ { "countryCode": "1", "phoneNumber": "1234567890" } ]
// },
// "actionGroupName": "ALZ action group",
// "actionGroupShortName": "alz-alert",
// "alertRuleName": "ALZ alert rule",
// "alertRuleDescription": "Alert rule for Azure Landing Zone"
// }
// }
@description('Service Health alerts')
param serviceHealthAlerts object = {}
// Log Analytics
@description('Log Analytics Resource Id to integrate Microsoft Defender for Cloud.')
param logAnalyticsWorkspaceResourceId string
// Microsoft Defender for Cloud
// Example (JSON)
// -----------------------------
// "securityCenter": {
// "value": {
// "email": "alzcanadapubsec@microsoft.com",
// "phone": "5555555555"
// }
// }
// Example (Bicep)
// -----------------------------
// {
// email: 'alzcanadapubsec@microsoft.com'
// phone: '5555555555'
// }
@description('Microsoft Defender for Cloud configuration. It includes email and phone.')
param securityCenter object
// Subscription Role Assignments
// Example (JSON)
// -----------------------------
// [
// {
// "comments": "Built-in Contributor Role",
// "roleDefinitionId": "b24988ac-6180-42a0-ab88-20f7382dd24c",
// "securityGroupObjectIds": [
// "38f33f7e-a471-4630-8ce9-c6653495a2ee"
// ]
// }
// ]
// Example (Bicep)
// -----------------------------
// [
// {
// comments: 'Built-In Contributor Role'
// roleDefinitionId: 'b24988ac-6180-42a0-ab88-20f7382dd24c'
// securityGroupObjectIds: [
// '38f33f7e-a471-4630-8ce9-c6653495a2ee'
// ]
// }
// ]
@description('Array of role assignments at subscription scope. The array will contain an object with comments, roleDefinitionId and array of securityGroupObjectIds.')
param subscriptionRoleAssignments array = []
// Subscription Budget
// Example (JSON)
// ---------------------------
// "subscriptionBudget": {
// "value": {
// "createBudget": false,
// "name": "MonthlySubscriptionBudget",
// "amount": 1000,
// "timeGrain": "Monthly",
// "contactEmails": [ "alzcanadapubsec@microsoft.com" ]
// }
// }
// Example (Bicep)
// ---------------------------
// {
// createBudget: true
// name: 'MonthlySubscriptionBudget'
// amount: 1000
// timeGrain: 'Monthly'
// contactEmails: [
// 'alzcanadapubsec@microsoft.com'
// ]
// }
@description('Subscription budget configuration containing createBudget flag, name, amount, timeGrain and array of contactEmails')
param subscriptionBudget object
// Tags
// Example (JSON)
// -----------------------------
// "subscriptionTags": {
// "value": {
// "ISSO": "isso-tag"
// }
// }
// Example (Bicep)
// ---------------------------
// {
// ISSO: 'isso-tag'
// }
@description('A set of key/value pairs of tags assigned to the subscription.')
param subscriptionTags object
// Example (JSON)
// -----------------------------
// "resourceTags": {
// "value": {
// "ClientOrganization": "client-organization-tag",
// "CostCenter": "cost-center-tag",
// "DataSensitivity": "data-sensitivity-tag",
// "ProjectContact": "project-contact-tag",
// "ProjectName": "project-name-tag",
// "TechnicalContact": "technical-contact-tag"
// }
// }
// Example (Bicep)
// -----------------------------
// {
// ClientOrganization: 'client-organization-tag'
// CostCenter: 'cost-center-tag'
// DataSensitivity: 'data-sensitivity-tag'
// ProjectContact: 'project-contact-tag'
// ProjectName: 'project-name-tag'
// TechnicalContact: 'technical-contact-tag'
// }
@description('A set of key/value pairs of tags assigned to the resource group and resources.')
param resourceTags object
// Resource Groups
@description('Resource groups required for the archetype. It includes automation, networking and networkWatcher.')
param resourceGroups object
// RecoveryVault
@description('Azure recovery vault configuration containing enabled flag, and name')
param backupRecoveryVault object
// Azure Automation Account
@description('Azure Automation Account configuration. Includes name.')
param automation object
// Networking
@description('Hub Network configuration that includes virtualNetworkId, rfc1918IPRange, rfc6598IPRange and egressVirtualApplianceIp.')
param hubNetwork object
@description('Network configuration for the spoke virtual network. It includes name, dns services, address spaces, vnet peering and subnets.')
param network object
// Private Dns Zones
@description('Private DNS Zones configuration. See docs/archetypes/identity.md for configuration settings.')
param privateDnsZones object
// Private DNS Resolver
@description('Private DNS Resolver configuration for Inbound connections.')
param privateDnsResolver object
// Private DNS Resolver Ruleset
@description('Private DNS Resolver Default Ruleset Configuration')
param privateDnsResolverRuleset object
// Telemetry - Azure customer usage attribution
// Reference: https://docs.microsoft.com/azure/marketplace/azure-partner-customer-usage-attribution
var telemetry = json(loadTextContent('../../config/telemetry.json'))
module telemetryCustomerUsageAttribution '../../azresources/telemetry/customer-usage-attribution-subscription.bicep' = if (telemetry.customerUsageAttribution.enabled) {
name: 'pid-${telemetry.customerUsageAttribution.modules.identity}'
}
/*
Scaffold the subscription which includes:
* Microsoft Defender for Cloud - Enable Azure Defender (all available options)
* Microsoft Defender for Cloud - Configure Log Analytics Workspace
* Microsoft Defender for Cloud - Configure Security Alert Contact
* Service Health Alerts
* Role Assignments to Security Groups
* Subscription Budget
* Subscription Tags
*/
module subScaffold '../scaffold-subscription.bicep' = {
name: 'configure-subscription'
scope: subscription()
params: {
location: location
serviceHealthAlerts: serviceHealthAlerts
logAnalyticsWorkspaceResourceId: logAnalyticsWorkspaceResourceId
securityCenter: securityCenter
subscriptionBudget: subscriptionBudget
subscriptionTags: subscriptionTags
resourceTags: resourceTags
subscriptionRoleAssignments: subscriptionRoleAssignments
}
}
// Create Network Watcher Resource Group
resource rgNetworkWatcher 'Microsoft.Resources/resourceGroups@2020-06-01' = {
name: resourceGroups.networkWatcher
location: location
tags: resourceTags
}
// Create Virtual Network Resource Group - only if Virtual Network is being deployed
resource rgVnet 'Microsoft.Resources/resourceGroups@2020-06-01' = if (network.deployVnet) {
name: network.deployVnet ? resourceGroups.networking : 'placeholder'
location: location
tags: resourceTags
}
// Create Azure Automation Resource Group
resource rgAutomation 'Microsoft.Resources/resourceGroups@2020-06-01' = {
name: resourceGroups.automation
location: location
tags: resourceTags
}
// Create Azure backup RecoveryVault Resource Group
resource rgBackupVault 'Microsoft.Resources/resourceGroups@2020-06-01' =if (backupRecoveryVault.enabled) {
name: resourceGroups.backupRecoveryVault
location: location
tags: resourceTags
}
// Create Private DNS Zones Resource Group
resource rgPrivateDnsZones 'Microsoft.Resources/resourceGroups@2020-06-01' =if (privateDnsZones.enabled) {
name: resourceGroups.privateDnsZones
location: location
tags: resourceTags
}
// Create automation account
module automationAccount '../../azresources/automation/automation-account.bicep' = {
name: 'deploy-automation-account'
scope: rgAutomation
params: {
automationAccountName: automation.name
tags: resourceTags
location: location
}
}
//create recovery vault for backup of vms
module backupVault '../../azresources/management/backup-recovery-vault.bicep'= if(backupRecoveryVault.enabled){
name:'deploy-backup-recoveryvault'
scope: rgBackupVault
params:{
vaultName: backupRecoveryVault.name
tags: resourceTags
location: location
}
}
// Create & configure virtaual network - only if Virtual Network is being deployed
module vnet 'networking.bicep' = if (network.deployVnet) {
name: 'deploy-networking'
scope: resourceGroup(rgVnet.name)
params: {
hubNetwork: hubNetwork
network: network
location: location
deployDNSResolver: privateDnsResolver
}
}
module dnsResolver 'dnsResolver.bicep' = if (privateDnsResolver.enabled) {
name: 'deploy-dns-resolver'
scope: subscription()
params: {
privateDnsResolver: privateDnsResolver
location: location
rgVnet: rgVnet.name
vnetId: vnet.outputs.vnetId
vnetName: vnet.outputs.vnetName
network: network
resourceTags: resourceTags
privateDnsResolverRuleset: privateDnsResolverRuleset
dnsResolverRG: resourceGroups.dnsResolver
}
}
// Private DNS Zones
module privatelinkDnsZones '../../azresources/network/private-dns-zone-privatelinks.bicep' = if (privateDnsZones.enabled) {
name: 'deploy-privatelink-private-dns-zones'
scope: resourceGroup(resourceGroups.privateDnsZones)
params: {
vnetId: vnet.outputs.vnetId
dnsCreateNewZone: true
dnsLinkToVirtualNetwork: true
// Not required since the private dns zones will be created and linked to hub virtual network.
dnsExistingZoneSubscriptionId: ''
dnsExistingZoneResourceGroupName: ''
}
}

Просмотреть файл

@ -0,0 +1,404 @@
// ----------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
// EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
// ----------------------------------------------------------------------------------
@description('Location for the deployment.')
param location string = resourceGroup().location
// Networking
// Example (JSON)
// -----------------------------
// "hubNetwork": {
// "value": {
// "virtualNetworkId": "/subscriptions/ed7f4eed-9010-4227-b115-2a5e37728f27/resourceGroups/pubsec-hub-networking/providers/Microsoft.Network/virtualNetworks/hub-vnet",
// "rfc1918IPRange": "10.18.0.0/22",
// "rfc6598IPRange": "100.60.0.0/16",
// "egressVirtualApplianceIp": "10.18.0.36",
// "privateDnsManagedByHub": true,
// "privateDnsManagedByHubSubscriptionId": "ed7f4eed-9010-4227-b115-2a5e37728f27",
// "privateDnsManagedByHubResourceGroupName": "pubsec-dns"
// }
// }
// Example (Bicep)
// -----------------------------
// {
// virtualNetworkId: '/subscriptions/ed7f4eed-9010-4227-b115-2a5e37728f27/resourceGroups/pubsec-hub-networking/providers/Microsoft.Network/virtualNetworks/hub-vnet'
// rfc1918IPRange: '10.18.0.0/22'
// rfc6598IPRange: '100.60.0.0/16'
// egressVirtualApplianceIp: '10.18.0.36'
// privateDnsManagedByHub: true,
// privateDnsManagedByHubSubscriptionId: 'ed7f4eed-9010-4227-b115-2a5e37728f27',
// privateDnsManagedByHubResourceGroupName: 'pubsec-dns'
// }
@description('Hub Network configuration that includes virtualNetworkId, rfc1918IPRange, rfc6598IPRange, egressVirtualApplianceIp, privateDnsManagedByHub flag, privateDnsManagedByHubSubscriptionId and privateDnsManagedByHubResourceGroupName.')
param hubNetwork object
// Example (JSON)
// -----------------------------
// "network": {
// "value": {
// "peerToHubVirtualNetwork": true,
// "useRemoteGateway": false,
// "name": "vnet",
// "dnsServers": [
// "10.18.1.4"
// ],
// "addressPrefixes": [
// "10.2.0.0/16"
// ],
// "subnets": {
// "privateEndpoints": {
// "comments": "Private Endpoints Subnet",
// "name": "privateendpoints",
// "addressPrefix": "10.2.5.0/25"
// },
// "sqlmi": {
// "comments": "SQL Managed Instances Delegated Subnet",
// "name": "sqlmi",
// "addressPrefix": "10.2.6.0/25"
// },
// "databricksPublic": {
// "comments": "Databricks Public Delegated Subnet",
// "name": "databrickspublic",
// "addressPrefix": "10.2.7.0/25"
// },
// "databricksPrivate": {
// "comments": "Databricks Private Delegated Subnet",
// "name": "databricksprivate",
// "addressPrefix": "10.2.8.0/25"
// },
// "aks": {
// "comments": "AKS Subnet",
// "name": "aks",
// "addressPrefix": "10.2.9.0/25"
// },
// "appService": {
// "comments": "App Service Subnet",
// "name": "appService",
// "addressPrefix": "10.2.10.0/25"
// }
// "optional": [
// {
// "comments": "Optional Subnet 1",
// "name": "virtualMachines",
// "addressPrefix": "10.6.11.0/25",
// "nsg": {
// "enabled": true
// },
// "udr": {
// "enabled": true
// }
// },
// {
// "comments": "Optional Subnet 2 with delegation for NetApp Volumes",
// "name": "NetappVolumes",
// "addressPrefix": "10.6.12.0/25",
// "nsg": {
// "enabled": false
// },
// "udr": {
// "enabled": false
// },
// "delegations": {
// "serviceName": "Microsoft.NetApp/volumes"
// }
// }
// ]
// }
// }
// }
// Example (Bicep)
// -----------------------------
// {
// peerToHubVirtualNetwork: true
// useRemoteGateway: false
// name: 'vnet'
// dnsServers: [
// '10.18.1.4'
// ]
// addressPrefixes: [
// '10.2.0.0/16'
// ]
// subnets: {
// privateEndpoints: {
// comments: 'Private Endpoints Subnet'
// name: 'privateendpoints'
// addressPrefix: '10.2.5.0/25'
// }
// sqlmi: {
// comments: 'SQL Managed Instances Delegated Subnet'
// name: 'sqlmi'
// addressPrefix: '10.2.6.0/25'
// }
// databricksPublic: {
// comments: 'Databricks Public Delegated Subnet'
// name: 'databrickspublic'
// addressPrefix: '10.2.7.0/25'
// }
// databricksPrivate: {
// comments: 'Databricks Private Delegated Subnet'
// name: 'databricksprivate'
// addressPrefix: '10.2.8.0/25'
// }
// aks: {
// comments: 'AKS Subnet'
// name: 'aks'
// addressPrefix: '10.2.9.0/25'
// }
// appService: {
// comments: 'App Service Subnet'
// name: 'appService'
// addressPrefix: '10.2.10.0/25'
// }
// optional: [
// {
// comments: 'Optional Subnet 1'
// name: 'virtualMachines'
// addressPrefix: '10.6.11.0/25'
// nsg: {
// enabled: true
// },
// udr: {
// enabled: true
// }
// },
// {
// comments: 'Optional Subnet 2 with delegation for NetApp Volumes',
// name: 'NetappVolumes'
// addressPrefix: '10.6.12.0/25'
// nsg: {
// enabled: false
// },
// udr: {
// enabled: false
// },
// delegations: {
// serviceName: 'Microsoft.NetApp/volumes'
// }
// }
// ]
// }
// }
@description('Network configuration for the spoke virtual network. It includes name, dnsServers, address spaces, vnet peering and subnets.')
param network object
@description('Get the DNS Private Resolver enabled/disabled setting so the associated subnets can be optionally deployed based on the value.')
param deployDNSResolver object
var hubVnetIdSplit = split(hubNetwork.virtualNetworkId, '/')
var routesToHub = [
// Force Routes to Hub IPs (RFC1918 range) via FW despite knowing that route via peering
{
name: 'SpokeUdrHubRFC1918FWRoute'
properties: {
addressPrefix: hubNetwork.rfc1918IPRange
nextHopType: 'VirtualAppliance'
nextHopIpAddress: hubNetwork.egressVirtualApplianceIp
}
}
// Force Routes to Hub IPs (CGNAT range) via FW despite knowing that route via peering
{
name: 'SpokeUdrHubRFC6598FWRoute'
properties: {
addressPrefix: hubNetwork.rfc6598IPRange
nextHopType: 'VirtualAppliance'
nextHopIpAddress: hubNetwork.egressVirtualApplianceIp
}
}
{
name: 'RouteToEgressFirewall'
properties: {
addressPrefix: '0.0.0.0/0'
nextHopType: 'VirtualAppliance'
nextHopIpAddress: hubNetwork.egressVirtualApplianceIp
}
}
]
// Network Security Groups
resource nsg 'Microsoft.Network/networkSecurityGroups@2021-02-01' = [for subnet in network.subnets.optional: if (subnet.nsg.enabled) {
name: '${subnet.name}Nsg'
location: location
properties: {
securityRules: []
}
}]
module nsgDomainControllers '../../azresources/network/nsg/nsg-empty.bicep' = {
name: 'deploy-nsg-DomainControllers'
params: {
name: '${network.subnets.domainControllers.name}Nsg'
location: location
}
}
module nsgDnsResolverInbound '../../azresources/network/nsg/nsg-empty.bicep' = if (deployDNSResolver.enabled) {
name: 'deploy-nsg-dnsResolverInbound'
params: {
name: '${network.subnets.dnsResolverInbound.name}Nsg'
location: location
}
}
module nsgDnsResolverOutbound '../../azresources/network/nsg/nsg-empty.bicep' = if (deployDNSResolver.enabled) {
name: 'deploy-nsg-dnsResolverOutbound'
params: {
name: '${network.subnets.dnsResolverOutbound.name}Nsg'
location: location
}
}
// Route Tables
resource udr 'Microsoft.Network/routeTables@2021-02-01' = {
name: 'RouteTable'
location: location
properties: {
routes: network.peerToHubVirtualNetwork ? routesToHub : null
}
}
// Virtual Network
var requiredSubnets = [
{
name: network.subnets.domainControllers.name
properties: {
addressPrefix: network.subnets.domainControllers.addressPrefix
privateEndpointNetworkPolicies: 'Enabled'
routeTable: {
id: udr.id
}
networkSecurityGroup: {
id: nsgDomainControllers.outputs.nsgId
}
}
}
]
var dnsResolverSubnets = [
{
name: network.subnets.dnsResolverInbound.name
properties: {
addressPrefix: network.subnets.dnsResolverInbound.addressPrefix
privateEndpointNetworkPolicies: 'Enabled'
routeTable: {
id: udr.id
}
networkSecurityGroup: {
id: nsgDnsResolverInbound.outputs.nsgId
}
delegations: [
{
name: 'delAzureDNSResolverInbound'
properties: {
serviceName: 'Microsoft.Network/dnsResolvers'
}
}
]
}
}
{
name: network.subnets.dnsResolverOutbound.name
properties: {
addressPrefix: network.subnets.dnsResolverOutbound.addressPrefix
privateEndpointNetworkPolicies: 'Enabled'
routeTable: {
id: udr.id
}
networkSecurityGroup: {
id: nsgDnsResolverOutbound.outputs.nsgId
}
delegations: [
{
name: 'delAzureDNSResolverOutbound'
properties: {
serviceName: 'Microsoft.Network/dnsResolvers'
}
}
]
}
}
]
var optionalSubnets = [for (subnet, i) in network.subnets.optional: {
name: subnet.name
properties: {
addressPrefix: subnet.addressPrefix
networkSecurityGroup: (subnet.nsg.enabled) ? {
id: nsg[i].id
} : null
routeTable: (subnet.udr.enabled) ? {
id: udr.id
} : null
delegations: contains(subnet, 'delegations') ? [
{
name: replace(subnet.delegations.serviceName, '/', '.')
properties: {
serviceName: subnet.delegations.serviceName
}
}
] : null
}
}]
//Optionally add DNS Resolver subnets based on if the deployDNSResolver parameter is set to true
var allSubnets = deployDNSResolver.enabled ? union(requiredSubnets, optionalSubnets, dnsResolverSubnets) : union(requiredSubnets, optionalSubnets)
resource vnet 'Microsoft.Network/virtualNetworks@2021-02-01' = {
name: network.name
location: location
properties: {
dhcpOptions: {
dnsServers: network.dnsServers
}
addressSpace: {
addressPrefixes: network.addressPrefixes
}
subnets: allSubnets
}
}
module vnetPeeringSpokeToHub '../../azresources/network/vnet-peering.bicep' = if (network.peerToHubVirtualNetwork) {
name: 'deploy-vnet-peering-spoke-to-hub'
scope: resourceGroup()
params: {
peeringName: 'Hub-${vnet.name}-to-${last(hubVnetIdSplit)}'
allowForwardedTraffic: true
allowVirtualNetworkAccess: true
sourceVnetName: vnet.name
targetVnetId: hubNetwork.virtualNetworkId
useRemoteGateways: network.useRemoteGateway
}
}
// For Hub to Spoke vnet peering, we must rescope the deployment to the subscription id & resource group of where the Hub VNET is located.
module vnetPeeringHubToSpoke '../../azresources/network/vnet-peering.bicep' = if (network.peerToHubVirtualNetwork) {
name: 'deploy-vnet-peering-${subscription().subscriptionId}'
// vnet id = /subscriptions/<<SUBSCRIPTION ID>>/resourceGroups/<<RESOURCE GROUP>>/providers/Microsoft.Network/virtualNetworks/<<VNET NAME>>
scope: resourceGroup(network.peerToHubVirtualNetwork ? hubVnetIdSplit[2] : '', network.peerToHubVirtualNetwork ? hubVnetIdSplit[4] : '')
params: {
peeringName: 'Spoke-${last(hubVnetIdSplit)}-to-${vnet.name}-${uniqueString(vnet.id)}'
allowForwardedTraffic: true
allowVirtualNetworkAccess: true
sourceVnetName: last(hubVnetIdSplit)!
targetVnetId: vnet.id
useRemoteGateways: false
}
}
output vnetId string = vnet.id
output vnetName string = vnet.name

Просмотреть файл

@ -0,0 +1,455 @@
{
"$schema": "http://json-schema.org/draft-06/schema#",
"$ref": "#/definitions/PlatformIdentityArchetypeDefinition",
"definitions": {
"PlatformIdentityArchetypeDefinition": {
"type": "object",
"additionalProperties": false,
"properties": {
"$schema": {
"type": "string",
"format": "uri",
"qt-uri-protocols": [
"https"
],
"qt-uri-extensions": [
".json"
]
},
"contentVersion": {
"type": "string"
},
"parameters": {
"$ref": "#/definitions/Parameters"
}
},
"required": [
"$schema",
"contentVersion",
"parameters"
],
"title": "PlatformIdentityArchetypeDefinition"
},
"Parameters": {
"type": "object",
"additionalProperties": false,
"properties": {
"location": {
"$ref": "types/location.json#/definitions/Location"
},
"logAnalyticsWorkspaceResourceId": {
"$ref": "types/logAnalyticsWorkspaceId.json#/definitions/LogAnalyticsWorkspaceId"
},
"serviceHealthAlerts": {
"$ref": "types/serviceHealthAlerts.json#/definitions/ServiceHealthAlerts"
},
"securityCenter": {
"$ref": "types/securityCenter.json#/definitions/SecurityCenter"
},
"subscriptionRoleAssignments": {
"$ref": "types/subscriptionRoleAssignments.json#/definitions/SubscriptionRoleAssignments"
},
"subscriptionBudget": {
"$ref": "types/subscriptionBudget.json#/definitions/SubscriptionBudget"
},
"subscriptionTags": {
"$ref": "types/subscriptionTags.json#/definitions/SubscriptionTags"
},
"resourceTags": {
"$ref": "types/resourceTags.json#/definitions/ResourceTags"
},
"resourceGroups": {
"$ref": "#/definitions/ResourceGroups"
},
"automation": {
"$ref": "types/automation.json#/definitions/Automation"
},
"backupRecoveryVault": {
"$ref": "types/backupRecoveryVault.json#/definitions/RecoveryVault"
},
"privateDnsZones": {
"$ref": "#/definitions/PrivateDNSZones"
},
"privateDnsResolver": {
"$ref": "#/definitions/PrivateDNSResolver"
},
"privateDnsResolverRuleset": {
"$ref": "#/definitions/PrivateDNSResolverRuleset"
},
"hubNetwork": {
"$ref": "#/definitions/HubNetwork"
},
"network": {
"$ref": "#/definitions/Network"
}
},
"required": [
"automation",
"backupRecoveryVault",
"hubNetwork",
"network",
"privateDnsResolver",
"privateDnsResolverRuleset",
"privateDnsZones",
"resourceGroups",
"resourceTags",
"securityCenter",
"serviceHealthAlerts",
"subscriptionBudget",
"subscriptionRoleAssignments",
"subscriptionTags"
],
"title": "Parameters"
},
"HubNetwork": {
"type": "object",
"additionalProperties": false,
"properties": {
"value": {
"$ref": "#/definitions/HubNetworkValue"
}
},
"required": [
"value"
],
"title": "HubNetwork"
},
"HubNetworkValue": {
"type": "object",
"additionalProperties": false,
"properties": {
"virtualNetworkId": {
"type": "string"
},
"rfc1918IPRange": {
"type": "string"
},
"rfc6598IPRange": {
"type": "string"
},
"egressVirtualApplianceIp": {
"type": "string"
}
},
"required": [
"egressVirtualApplianceIp",
"rfc1918IPRange",
"rfc6598IPRange",
"virtualNetworkId"
],
"title": "HubNetworkValue"
},
"DNSResolverInbound": {
"type": "object",
"additionalProperties": false,
"properties": {
"comments": {
"type": "string"
},
"name": {
"type": "string"
},
"addressPrefix": {
"type": "string"
}
},
"required": [
"addressPrefix",
"comments",
"name"
],
"title": "DNSResolverInbound"
},
"PrivateDNSResolver": {
"type": "object",
"additionalProperties": false,
"properties": {
"value": {
"$ref": "#/definitions/PrivateDNSResolverValue"
}
},
"required": [
"value"
],
"title": "PrivateDNSResolver"
},
"PrivateDNSResolverValue": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": {
"type": "boolean"
},
"name": {
"type": "string"
},
"inboundEndpointName": {
"type": "string"
},
"outboundEndpointName": {
"type": "string"
}
},
"required": [
"enabled",
"inboundEndpointName",
"name",
"outboundEndpointName"
],
"title": "PrivateDNSResolverValue"
},
"PrivateDNSResolverRuleset": {
"type": "object",
"additionalProperties": false,
"properties": {
"value": {
"$ref": "#/definitions/PrivateDNSResolverRulesetValue"
}
},
"required": [
"value"
],
"title": "PrivateDNSResolverRuleset"
},
"PrivateDNSResolverRulesetValue": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": {
"type": "boolean"
},
"name": {
"type": "string"
},
"linkRuleSetToVnet": {
"type": "boolean"
},
"linkRuleSetToVnetName": {
"type": "string"
},
"forwardingRules": {
"type": "array",
"items": {
"$ref": "#/definitions/ForwardingRule"
}
}
},
"required": [
"enabled",
"forwardingRules",
"linkRuleSetToVnet",
"linkRuleSetToVnetName",
"name"
],
"title": "PrivateDNSResolverRulesetValue"
},
"ForwardingRule": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string"
},
"domain": {
"type": "string"
},
"state": {
"type": "string"
},
"targetDnsServers": {
"type": "array",
"items": {
"$ref": "#/definitions/TargetDNSServer"
}
}
},
"required": [
"domain",
"name",
"state",
"targetDnsServers"
],
"title": "ForwardingRule"
},
"TargetDNSServer": {
"type": "object",
"additionalProperties": false,
"properties": {
"ipAddress": {
"type": "string"
}
},
"required": [
"ipAddress"
],
"title": "TargetDNSServer"
},
"PrivateDNSZones": {
"type": "object",
"additionalProperties": false,
"properties": {
"value": {
"$ref": "#/definitions/PrivateDNSZonesValue"
}
},
"required": [
"value"
],
"title": "PrivateDNSZones"
},
"PrivateDNSZonesValue": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": {
"type": "boolean"
},
"resourceGroupName": {
"type": "string"
}
},
"required": [
"enabled",
"resourceGroupName"
],
"title": "PrivateDNSZonesValue"
},
"ResourceGroups": {
"type": "object",
"additionalProperties": false,
"properties": {
"value": {
"$ref": "#/definitions/ResourceGroupsValue"
}
},
"required": [
"value"
],
"title": "ResourceGroups"
},
"ResourceGroupsValue": {
"type": "object",
"additionalProperties": false,
"properties": {
"automation": {
"type": "string"
},
"networking": {
"type": "string"
},
"networkWatcher": {
"type": "string"
},
"backupRecoveryVault": {
"type": "string"
},
"domainControllers": {
"type": "string"
},
"dnsResolver": {
"type": "string"
},
"dnsCondionalForwarders": {
"type": "string"
},
"privateDnsZones": {
"type": "string"
}
},
"required": [
"automation",
"backupRecoveryVault",
"dnsCondionalForwarders",
"dnsResolver",
"domainControllers",
"networkWatcher",
"networking",
"privateDnsZones"
],
"title": "ResourceGroupsValue"
},
"Network": {
"type": "object",
"additionalProperties": false,
"properties": {
"value": {
"$ref": "#/definitions/NetworkValue"
}
},
"required": [
"value"
],
"title": "Network"
},
"NetworkValue": {
"type": "object",
"additionalProperties": false,
"properties": {
"deployVnet": {
"type": "boolean"
},
"peerToHubVirtualNetwork": {
"type": "boolean"
},
"useRemoteGateway": {
"type": "boolean"
},
"name": {
"type": "string"
},
"dnsServers": {
"type": "array",
"items": {
"type": "string"
}
},
"addressPrefixes": {
"type": "array",
"items": {
"type": "string"
}
},
"subnets": {
"$ref": "#/definitions/Subnets"
}
},
"required": [
"addressPrefixes",
"deployVnet",
"dnsServers",
"name",
"peerToHubVirtualNetwork",
"subnets",
"useRemoteGateway"
],
"title": "NetworkValue"
},
"Subnets": {
"type": "object",
"additionalProperties": false,
"properties": {
"domainControllers": {
"$ref": "#/definitions/DNSResolverInbound"
},
"dnsResolverInbound": {
"$ref": "#/definitions/DNSResolverInbound"
},
"dnsResolverOutbound": {
"$ref": "#/definitions/DNSResolverInbound"
},
"optional": {
"type": "array",
"items": {}
}
},
"required": [
"dnsResolverInbound",
"dnsResolverOutbound",
"domainControllers",
"optional"
],
"title": "Subnets"
}
}
}

Просмотреть файл

@ -49,6 +49,7 @@ function New-EnvironmentContext {
LoggingDirectory = "$WorkingDirectory/config/logging/$Environment"
NetworkingDirectory = "$WorkingDirectory/config/networking/$Environment"
SubscriptionsDirectory = "$WorkingDirectory/config/subscriptions/$Environment"
IdentityDirectory = "$WorkingDirectory/config/identity/$Environment"
Variables = $Variables
ManagementGroupHierarchy = $ManagementGroupHierarchy

Просмотреть файл

@ -0,0 +1,81 @@
<#
----------------------------------------------------------------------------------
Copyright (c) Microsoft Corporation.
Licensed under the MIT license.
THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
----------------------------------------------------------------------------------
#>
function Set-Identity {
param (
[Parameter(Mandatory = $true)]
$Context,
[Parameter(Mandatory = $true)]
[String]$Region,
[Parameter(Mandatory = $true)]
[String]$ManagementGroupId,
[Parameter(Mandatory = $true)]
[String]$SubscriptionId,
[Parameter(Mandatory = $true)]
[String]$ConfigurationFilePath,
[Parameter(Mandatory = $true)]
[String]$LogAnalyticsWorkspaceResourceId
)
Set-AzContext -Subscription $SubscriptionId
$SchemaFilePath = "$($Context.SchemaDirectory)/landingzones/lz-platform-identity.json"
Write-Output "Validation JSON parameter configuration using $SchemaFilePath"
Get-Content -Raw $ConfigurationFilePath | Test-Json -SchemaFile $SchemaFilePath
# Load networking configuration
$Configuration = Get-Content $ConfigurationFilePath | ConvertFrom-Json -Depth 100
#region Check if Log Analytics Workspace Id is provided. Otherwise set it.
$LogAnalyticsWorkspaceResourceIdInFile = $Configuration.parameters | Get-Member -Name logAnalyticsWorkspaceResourceId
if ($null -eq $LogAnalyticsWorkspaceResourceIdInFile -or $Configuration.parameters.logAnalyticsWorkspaceResourceId.value -eq "") {
$LogAnalyticsWorkspaceIdElement = @{
logAnalyticsWorkspaceResourceId = @{
value = $LogAnalyticsWorkspaceResourceId
}
}
$Configuration.parameters | Add-Member $LogAnalyticsWorkspaceIdElement -Force
}
#endregion
$PopulatedParametersFilePath = $ConfigurationFilePath.Split('.')[0] + '-populated.json'
Write-Output "Creating new file with runtime populated parameters: $PopulatedParametersFilePath"
$Configuration | ConvertTo-Json -Depth 100 | Set-Content $PopulatedParametersFilePath
Write-Output "Moving Subscription ($SubscriptionId) to Management Group ($ManagementGroupId)"
New-AzManagementGroupDeployment `
-ManagementGroupId $ManagementGroupId `
-Location $Context.DeploymentRegion `
-TemplateFile "$($Context.WorkingDirectory)/landingzones/utils/mg-move/move-subscription.bicep" `
-TemplateParameterObject @{
managementGroupId = $ManagementGroupId
subscriptionId = $SubscriptionId
} `
-Verbose
Write-Output "Deploying Identity to $SubscriptionId in $Region with $ConfigurationFilePath"
New-AzSubscriptionDeployment `
-Name "main-$Region" `
-Location $Region `
-TemplateFile "$($Context.WorkingDirectory)/landingzones/lz-platform-identity/main.bicep" `
-TemplateParameterFile $PopulatedParametersFilePath `
-Verbose
}

Просмотреть файл

@ -62,6 +62,9 @@ OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
.PARAMETER DeployHubNetworkWithNVA
If true, run the NVA hub network workflow.
.PARAMETER DeployIdentity
If true, run the Identity workflow.
.PARAMETER DeploySubscriptionIds
Comma separated list of quoted subscription ids to run the subscription workflow against.
@ -173,6 +176,8 @@ Param(
[switch]$DeployHubNetworkWithNVA,
[switch]$DeployHubNetworkWithAzureFirewall,
[switch]$DeployIdentity,
[string[]]$DeploySubscriptionIds=@(),
# How to deploy
@ -220,6 +225,7 @@ Write-Host "Loading functions..."
. ".\Functions\Policy.ps1"
. ".\Functions\HubNetworkWithNVA.ps1"
. ".\Functions\HubNetworkWithAzureFirewall.ps1"
. ".\Functions\Identity.ps1"
. ".\Functions\Subscriptions.ps1"
# Az Login interactively
@ -393,6 +399,24 @@ if ($DeployHubNetworkWithAzureFirewall) {
-LogAnalyticsWorkspaceResourceId $LoggingConfiguration.LogAnalyticsWorkspaceResourceId
}
# Deploy Identity Subscription
if ($DeployIdentity) {
Write-Host "Deploying Identity Subscription..."
# Get Logging information using logging config file
$LoggingConfiguration = Get-LoggingConfiguration `
-ConfigurationFilePath "$($Context.LoggingDirectory)/$($Context.Variables['var-logging-configurationFileName'])" `
-SubscriptionId $Context.Variables['var-logging-subscriptionId']
#Create Identity Subscription
Set-Identity `
-Context $Context `
-Region $Context.Variables['var-identity-region'] `
-ManagementGroupId $Context.Variables['var-identity-managementGroupId'] `
-SubscriptionId $Context.Variables['var-identity-subscriptionId'] `
-ConfigurationFilePath "$($Context.IdentityDirectory)/$($Context.Variables['var-identity-configurationFileName'])" `
-LogAnalyticsWorkspaceResourceId $LoggingConfiguration.LogAnalyticsWorkspaceResourceId
}
# Deploy Subscription archetypes
if (($null -ne $DeploySubscriptionIds) -and ($DeploySubscriptionIds.Count -gt 0)) {
Write-Host "Deploying Subscriptions..."

Просмотреть файл

@ -0,0 +1,170 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"serviceHealthAlerts": {
"value": {
"resourceGroupName": "service-health",
"incidentTypes": [ "Incident", "Security" ],
"regions": [ "Global", "Canada East", "Canada Central" ],
"receivers": {
"app": [ "alzcanadapubsec@microsoft.com" ],
"email": [ "alzcanadapubsec@microsoft.com" ],
"sms": [ { "countryCode": "1", "phoneNumber": "6045555555" } ],
"voice": [ { "countryCode": "1", "phoneNumber": "6045555555" } ]
},
"actionGroupName": "Service health action group",
"actionGroupShortName": "health-alert",
"alertRuleName": "Incidents and Security",
"alertRuleDescription": "Service Health: Incidents and Security"
}
},
"securityCenter": {
"value": {
"email": "alzcanadapubsec@microsoft.com",
"phone": "6045555555"
}
},
"subscriptionRoleAssignments": {
"value": [
{
"comments": "Built-in Owner Role",
"roleDefinitionId": "8e3af657-a8ff-443c-a75c-2fe8c4bcb635",
"securityGroupObjectIds": [
"3a4fa072-cc14-471d-aeac-49afdbde9f7a"
]
}
]
},
"subscriptionBudget": {
"value": {
"createBudget": false
}
},
"subscriptionTags": {
"value": {
"ISSO": "isso-tbd",
"ClientOrganization": "client-organization-tag",
"CostCenter": "cost-center-tag",
"DataSensitivity": "data-sensitivity-tag",
"ProjectContact": "project-contact-tag",
"ProjectName": "project-name-tag",
"TechnicalContact": "technical-contact-tag"
}
},
"resourceTags": {
"value": {
"ClientOrganization": "client-organization-tag",
"CostCenter": "cost-center-tag",
"DataSensitivity": "data-sensitivity-tag",
"ProjectContact": "project-contact-tag",
"ProjectName": "project-name-tag",
"TechnicalContact": "technical-contact-tag"
}
},
"resourceGroups": {
"value": {
"automation": "automation",
"networking": "networking",
"networkWatcher": "NetworkWatcherRG",
"backupRecoveryVault": "backup",
"domainControllers": "DomainControllersRG",
"dnsResolver": "dns-resolverRG",
"dnsCondionalForwarders": "dns-CondionalForwardersRG",
"privateDnsZones": "pubsec-dns"
}
},
"automation": {
"value": {
"name": "automation"
}
},
"backupRecoveryVault": {
"value": {
"enabled": true,
"name": "backup-vault"
}
},
"privateDnsZones": {
"value": {
"enabled": false,
"resourceGroupName": "pubsec-dns"
}
},
"privateDnsResolver": {
"value": {
"enabled": true,
"name": "dns-resolver",
"inboundEndpointName": "dns-resolver-Inbound",
"outboundEndpointName": "dns-resolver-Outbound"
}
},
"privateDnsResolverRuleset": {
"value": {
"enabled": true,
"name": "dns-resolver-ruleset",
"linkRuleSetToVnet": true,
"linkRuleSetToVnetName": "dns-resolver-vnet-link",
"forwardingRules": [
{
"name": "default",
"domain": "dontMakeMeThink.local",
"state": "Enabled",
"targetDnsServers": [
{
"ipAddress": "10.99.99.100"
},
{
"ipAddress": "10.99.99.99"
}
]
}
]
}
},
"hubNetwork": {
"value": {
"virtualNetworkId": "/subscriptions/ed7f4eed-9010-4227-b115-2a5e37728f27/resourceGroups/pubsec-hub-networking/providers/Microsoft.Network/virtualNetworks/hub-vnet",
"rfc1918IPRange": "10.18.0.0/22",
"rfc6598IPRange": "100.60.0.0/16",
"egressVirtualApplianceIp": "10.18.1.4"
}
},
"network": {
"value": {
"deployVnet": true,
"peerToHubVirtualNetwork": true,
"useRemoteGateway": false,
"name": "id-vnet",
"dnsServers": [
"10.18.1.4"
],
"addressPrefixes": [
"10.15.0.0/24"
],
"subnets": {
"domainControllers": {
"comments": "Identity Subnet for Domain Controllers and VM-Based DNS Servers",
"name": "DomainControllers",
"addressPrefix": "10.15.0.0/27"
},
"dnsResolverInbound": {
"comments": "Azure DNS Resolver Inbound Requests subnet",
"name": "AzureDNSResolver-Inbound",
"addressPrefix": "10.15.0.32/27"
},
"dnsResolverOutbound": {
"comments": "Azure DNS Resolver Outbound Requests subnet",
"name": "AzureDNSResolver-Outbound",
"addressPrefix": "10.15.0.64/27"
},
"optional": []
}
}
}
}
}

Просмотреть файл

@ -0,0 +1,170 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"serviceHealthAlerts": {
"value": {
"resourceGroupName": "service-health",
"incidentTypes": [ "Incident", "Security" ],
"regions": [ "Global", "Canada East", "Canada Central" ],
"receivers": {
"app": [ "alzcanadapubsec@microsoft.com" ],
"email": [ "alzcanadapubsec@microsoft.com" ],
"sms": [ { "countryCode": "1", "phoneNumber": "6045555555" } ],
"voice": [ { "countryCode": "1", "phoneNumber": "6045555555" } ]
},
"actionGroupName": "Service health action group",
"actionGroupShortName": "health-alert",
"alertRuleName": "Incidents and Security",
"alertRuleDescription": "Service Health: Incidents and Security"
}
},
"securityCenter": {
"value": {
"email": "alzcanadapubsec@microsoft.com",
"phone": "6045555555"
}
},
"subscriptionRoleAssignments": {
"value": [
{
"comments": "Built-in Owner Role",
"roleDefinitionId": "8e3af657-a8ff-443c-a75c-2fe8c4bcb635",
"securityGroupObjectIds": [
"3a4fa072-cc14-471d-aeac-49afdbde9f7a"
]
}
]
},
"subscriptionBudget": {
"value": {
"createBudget": false
}
},
"subscriptionTags": {
"value": {
"ISSO": "isso-tbd",
"ClientOrganization": "client-organization-tag",
"CostCenter": "cost-center-tag",
"DataSensitivity": "data-sensitivity-tag",
"ProjectContact": "project-contact-tag",
"ProjectName": "project-name-tag",
"TechnicalContact": "technical-contact-tag"
}
},
"resourceTags": {
"value": {
"ClientOrganization": "client-organization-tag",
"CostCenter": "cost-center-tag",
"DataSensitivity": "data-sensitivity-tag",
"ProjectContact": "project-contact-tag",
"ProjectName": "project-name-tag",
"TechnicalContact": "technical-contact-tag"
}
},
"resourceGroups": {
"value": {
"automation": "automation",
"networking": "networking",
"networkWatcher": "NetworkWatcherRG",
"backupRecoveryVault": "backup",
"domainControllers": "DomainControllersRG",
"dnsResolver": "dns-resolverRG",
"dnsCondionalForwarders": "dns-CondionalForwardersRG",
"privateDnsZones": "pubsec-dns"
}
},
"automation": {
"value": {
"name": "automation"
}
},
"backupRecoveryVault": {
"value": {
"enabled": true,
"name": "backup-vault"
}
},
"privateDnsZones": {
"value": {
"enabled": true,
"resourceGroupName": "pubsec-dns"
}
},
"privateDnsResolver": {
"value": {
"enabled": true,
"name": "dns-resolver",
"inboundEndpointName": "dns-resolver-Inbound",
"outboundEndpointName": "dns-resolver-Outbound"
}
},
"privateDnsResolverRuleset": {
"value": {
"enabled": true,
"name": "dns-resolver-ruleset",
"linkRuleSetToVnet": true,
"linkRuleSetToVnetName": "dns-resolver-vnet-link",
"forwardingRules": [
{
"name": "default",
"domain": "dontMakeMeThink.local",
"state": "Enabled",
"targetDnsServers": [
{
"ipAddress": "10.99.99.100"
},
{
"ipAddress": "10.99.99.99"
}
]
}
]
}
},
"hubNetwork": {
"value": {
"virtualNetworkId": "/subscriptions/ed7f4eed-9010-4227-b115-2a5e37728f27/resourceGroups/pubsec-hub-networking/providers/Microsoft.Network/virtualNetworks/hub-vnet",
"rfc1918IPRange": "10.18.0.0/22",
"rfc6598IPRange": "100.60.0.0/16",
"egressVirtualApplianceIp": "10.18.1.4"
}
},
"network": {
"value": {
"deployVnet": true,
"peerToHubVirtualNetwork": true,
"useRemoteGateway": false,
"name": "id-vnet",
"dnsServers": [
"10.18.1.4"
],
"addressPrefixes": [
"10.15.0.0/24"
],
"subnets": {
"domainControllers": {
"comments": "Identity Subnet for Domain Controllers and VM-Based DNS Servers",
"name": "DomainControllers",
"addressPrefix": "10.15.0.0/27"
},
"dnsResolverInbound": {
"comments": "Azure DNS Resolver Inbound Requests subnet",
"name": "AzureDNSResolver-Inbound",
"addressPrefix": "10.15.0.32/27"
},
"dnsResolverOutbound": {
"comments": "Azure DNS Resolver Outbound Requests subnet",
"name": "AzureDNSResolver-Outbound",
"addressPrefix": "10.15.0.64/27"
},
"optional": []
}
}
}
}
}

Просмотреть файл

@ -0,0 +1,170 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"serviceHealthAlerts": {
"value": {
"resourceGroupName": "service-health",
"incidentTypes": [ "Incident", "Security" ],
"regions": [ "Global", "Canada East", "Canada Central" ],
"receivers": {
"app": [ "alzcanadapubsec@microsoft.com" ],
"email": [ "alzcanadapubsec@microsoft.com" ],
"sms": [ { "countryCode": "1", "phoneNumber": "6045555555" } ],
"voice": [ { "countryCode": "1", "phoneNumber": "6045555555" } ]
},
"actionGroupName": "Service health action group",
"actionGroupShortName": "health-alert",
"alertRuleName": "Incidents and Security",
"alertRuleDescription": "Service Health: Incidents and Security"
}
},
"securityCenter": {
"value": {
"email": "alzcanadapubsec@microsoft.com",
"phone": "6045555555"
}
},
"subscriptionRoleAssignments": {
"value": [
{
"comments": "Built-in Owner Role",
"roleDefinitionId": "8e3af657-a8ff-443c-a75c-2fe8c4bcb635",
"securityGroupObjectIds": [
"3a4fa072-cc14-471d-aeac-49afdbde9f7a"
]
}
]
},
"subscriptionBudget": {
"value": {
"createBudget": false
}
},
"subscriptionTags": {
"value": {
"ISSO": "isso-tbd",
"ClientOrganization": "client-organization-tag",
"CostCenter": "cost-center-tag",
"DataSensitivity": "data-sensitivity-tag",
"ProjectContact": "project-contact-tag",
"ProjectName": "project-name-tag",
"TechnicalContact": "technical-contact-tag"
}
},
"resourceTags": {
"value": {
"ClientOrganization": "client-organization-tag",
"CostCenter": "cost-center-tag",
"DataSensitivity": "data-sensitivity-tag",
"ProjectContact": "project-contact-tag",
"ProjectName": "project-name-tag",
"TechnicalContact": "technical-contact-tag"
}
},
"resourceGroups": {
"value": {
"automation": "automation",
"networking": "networking",
"networkWatcher": "NetworkWatcherRG",
"backupRecoveryVault": "backup",
"domainControllers": "DomainControllersRG",
"dnsResolver": "dns-resolverRG",
"dnsCondionalForwarders": "dns-CondionalForwardersRG",
"privateDnsZones": "pubsec-dns"
}
},
"automation": {
"value": {
"name": "automation"
}
},
"backupRecoveryVault": {
"value": {
"enabled": true,
"name": "backup-vault"
}
},
"privateDnsZones": {
"value": {
"enabled": true,
"resourceGroupName": "pubsec-dns"
}
},
"privateDnsResolver": {
"value": {
"enabled": false,
"name": "dns-resolver",
"inboundEndpointName": "dns-resolver-Inbound",
"outboundEndpointName": "dns-resolver-Outbound"
}
},
"privateDnsResolverRuleset": {
"value": {
"enabled": true,
"name": "dns-resolver-ruleset",
"linkRuleSetToVnet": true,
"linkRuleSetToVnetName": "dns-resolver-vnet-link",
"forwardingRules": [
{
"name": "default",
"domain": "dontMakeMeThink.local",
"state": "Enabled",
"targetDnsServers": [
{
"ipAddress": "10.99.99.100"
},
{
"ipAddress": "10.99.99.99"
}
]
}
]
}
},
"hubNetwork": {
"value": {
"virtualNetworkId": "/subscriptions/ed7f4eed-9010-4227-b115-2a5e37728f27/resourceGroups/pubsec-hub-networking/providers/Microsoft.Network/virtualNetworks/hub-vnet",
"rfc1918IPRange": "10.18.0.0/22",
"rfc6598IPRange": "100.60.0.0/16",
"egressVirtualApplianceIp": "10.18.1.4"
}
},
"network": {
"value": {
"deployVnet": true,
"peerToHubVirtualNetwork": true,
"useRemoteGateway": false,
"name": "id-vnet",
"dnsServers": [
"10.18.1.4"
],
"addressPrefixes": [
"10.15.0.0/24"
],
"subnets": {
"domainControllers": {
"comments": "Identity Subnet for Domain Controllers and VM-Based DNS Servers",
"name": "DomainControllers",
"addressPrefix": "10.15.0.0/27"
},
"dnsResolverInbound": {
"comments": "Azure DNS Resolver Inbound Requests subnet",
"name": "AzureDNSResolver-Inbound",
"addressPrefix": "10.15.0.32/27"
},
"dnsResolverOutbound": {
"comments": "Azure DNS Resolver Outbound Requests subnet",
"name": "AzureDNSResolver-Outbound",
"addressPrefix": "10.15.0.64/27"
},
"optional": []
}
}
}
}
}

Просмотреть файл

@ -0,0 +1,170 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"serviceHealthAlerts": {
"value": {
"resourceGroupName": "service-health",
"incidentTypes": [ "Incident", "Security" ],
"regions": [ "Global", "Canada East", "Canada Central" ],
"receivers": {
"app": [ "alzcanadapubsec@microsoft.com" ],
"email": [ "alzcanadapubsec@microsoft.com" ],
"sms": [ { "countryCode": "1", "phoneNumber": "6045555555" } ],
"voice": [ { "countryCode": "1", "phoneNumber": "6045555555" } ]
},
"actionGroupName": "Service health action group",
"actionGroupShortName": "health-alert",
"alertRuleName": "Incidents and Security",
"alertRuleDescription": "Service Health: Incidents and Security"
}
},
"securityCenter": {
"value": {
"email": "alzcanadapubsec@microsoft.com",
"phone": "6045555555"
}
},
"subscriptionRoleAssignments": {
"value": [
{
"comments": "Built-in Owner Role",
"roleDefinitionId": "8e3af657-a8ff-443c-a75c-2fe8c4bcb635",
"securityGroupObjectIds": [
"3a4fa072-cc14-471d-aeac-49afdbde9f7a"
]
}
]
},
"subscriptionBudget": {
"value": {
"createBudget": false
}
},
"subscriptionTags": {
"value": {
"ISSO": "isso-tbd",
"ClientOrganization": "client-organization-tag",
"CostCenter": "cost-center-tag",
"DataSensitivity": "data-sensitivity-tag",
"ProjectContact": "project-contact-tag",
"ProjectName": "project-name-tag",
"TechnicalContact": "technical-contact-tag"
}
},
"resourceTags": {
"value": {
"ClientOrganization": "client-organization-tag",
"CostCenter": "cost-center-tag",
"DataSensitivity": "data-sensitivity-tag",
"ProjectContact": "project-contact-tag",
"ProjectName": "project-name-tag",
"TechnicalContact": "technical-contact-tag"
}
},
"resourceGroups": {
"value": {
"automation": "automation",
"networking": "networking",
"networkWatcher": "NetworkWatcherRG",
"backupRecoveryVault": "backup",
"domainControllers": "DomainControllersRG",
"dnsResolver": "dns-resolverRG",
"dnsCondionalForwarders": "dns-CondionalForwardersRG",
"privateDnsZones": "pubsec-dns"
}
},
"automation": {
"value": {
"name": "automation"
}
},
"backupRecoveryVault": {
"value": {
"enabled": true,
"name": "backup-vault"
}
},
"privateDnsZones": {
"value": {
"enabled": false,
"resourceGroupName": "pubsec-dns"
}
},
"privateDnsResolver": {
"value": {
"enabled": false,
"name": "dns-resolver",
"inboundEndpointName": "dns-resolver-Inbound",
"outboundEndpointName": "dns-resolver-Outbound"
}
},
"privateDnsResolverRuleset": {
"value": {
"enabled": true,
"name": "dns-resolver-ruleset",
"linkRuleSetToVnet": true,
"linkRuleSetToVnetName": "dns-resolver-vnet-link",
"forwardingRules": [
{
"name": "default",
"domain": "dontMakeMeThink.local",
"state": "Enabled",
"targetDnsServers": [
{
"ipAddress": "10.99.99.100"
},
{
"ipAddress": "10.99.99.99"
}
]
}
]
}
},
"hubNetwork": {
"value": {
"virtualNetworkId": "/subscriptions/ed7f4eed-9010-4227-b115-2a5e37728f27/resourceGroups/pubsec-hub-networking/providers/Microsoft.Network/virtualNetworks/hub-vnet",
"rfc1918IPRange": "10.18.0.0/22",
"rfc6598IPRange": "100.60.0.0/16",
"egressVirtualApplianceIp": "10.18.1.4"
}
},
"network": {
"value": {
"deployVnet": true,
"peerToHubVirtualNetwork": true,
"useRemoteGateway": false,
"name": "id-vnet",
"dnsServers": [
"10.18.1.4"
],
"addressPrefixes": [
"10.15.0.0/24"
],
"subnets": {
"domainControllers": {
"comments": "Identity Subnet for Domain Controllers and VM-Based DNS Servers",
"name": "DomainControllers",
"addressPrefix": "10.15.0.0/27"
},
"dnsResolverInbound": {
"comments": "Azure DNS Resolver Inbound Requests subnet",
"name": "AzureDNSResolver-Inbound",
"addressPrefix": "10.15.0.32/27"
},
"dnsResolverOutbound": {
"comments": "Azure DNS Resolver Outbound Requests subnet",
"name": "AzureDNSResolver-Outbound",
"addressPrefix": "10.15.0.64/27"
},
"optional": []
}
}
}
}
}

Просмотреть файл

@ -12,6 +12,8 @@ pwsh -File ./validate-deployment-config.ps1 -SchemaFile '../../schemas/latest/l
pwsh -File ./validate-deployment-config.ps1 -SchemaFile '../../schemas/latest/landingzones/lz-platform-connectivity-hub-nva.json' -TestFolder '../../config/networking/*/hub-nva/' -FileFilter '*.json'
pwsh -File ./validate-deployment-config.ps1 -SchemaFile '../../schemas/latest/landingzones/lz-platform-identity.json' -TestFolder '../../config/identity/' -FileFilter '*.json'
pwsh -File ./validate-deployment-config.ps1 -SchemaFile '../../schemas/latest/landingzones/lz-generic-subscription.json' -TestFolder '../../config/subscriptions/' -FileFilter '*generic-subscription*.json'
pwsh -File ./validate-deployment-config.ps1 -SchemaFile '../../schemas/latest/landingzones/lz-machinelearning.json' -TestFolder '../../config/subscriptions/' -FileFilter '*machinelearning*.json'