Identity Archetype (#359)
* 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: 2a3584a7749e7b
Author: Barry Willis <bawillis@microsoft.com> Date: Fri Feb 24 16:10:37 2023 -0800 Merge remote-tracking branch 'origin/main' into IdentityLZ commit7749e7bf7a
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' commitf6555a4122
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 commit8edcb63d83
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 commit37123d7162
Author: Barry Willis <bawillis@microsoft.com> Date: Mon Feb 13 11:17:38 2023 -0800 updated AKS version in the Data Archetypes commit459b3c6275
Author: Barry Willis <bawillis@microsoft.com> Date: Mon Feb 13 08:55:13 2023 -0800 changed the servcie health number prefix to 604 commitcccf88662c
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 commit8e9628d26e
Author: Barry Willis <bawillis@microsoft.com> Date: Mon Feb 13 07:01:36 2023 -0800 fixed linter warnings in policy files commit6c2b2f7d2d
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 commitc58ba48f50
Author: Barry Willis <bawillis@microsoft.com> Date: Sat Feb 11 15:09:56 2023 -0800 Fixed the AKS policy deployment commitf9e8418b7e
Author: Barry Willis <bawillis@microsoft.com> Date: Sat Feb 11 14:04:22 2023 -0800 Fixed Bug on policy defnition commit1a3c82e446
Author: Barry Willis <bawillis@microsoft.com> Date: Fri Feb 10 19:09:02 2023 -0800 updated the linter rules commit20e188051a
Author: Barry Willis <bawillis@microsoft.com> Date: Fri Feb 10 18:52:18 2023 -0800 fixed the remaining linter errors in the policy definitions commit1610a28e35
Author: Barry Willis <bawillis@microsoft.com> Date: Fri Feb 10 18:27:14 2023 -0800 fixed the remaining linter warnings commit9f0e049fa0
Author: Barry Willis <bawillis@microsoft.com> Date: Fri Feb 10 17:31:21 2023 -0800 fixed BCP321 warning commit466d7b0c07
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 commit9362967e50
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 commit4bcbc28212
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: dfe0d9a0fa01e8
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:
Родитель
533765439f
Коммит
f13f6ec24f
|
@ -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 != ''
|
||||
|
||||
|
|
|
@ -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}
|
|
@ -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,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"
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
@ -84,6 +85,14 @@ jobs:
|
|||
Write-Host "Validating: $_ with $HubNetworkWithNVASchemaFile"
|
||||
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
|
||||
|
|
|
@ -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 |
|
||||
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 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
|
||||
|
||||
}
|
|
@ -61,6 +61,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'
|
||||
|
|
Загрузка…
Ссылка в новой задаче