From 607074aabbe65530278618e9c5aee3eb70825a7f Mon Sep 17 00:00:00 2001 From: Senthuran Sivananthan Date: Thu, 28 Apr 2022 10:08:35 -0400 Subject: [PATCH 01/31] PS scaffolding for deploying MGs, Roles and Logging --- .../deployments/00-Install-Prerequisites.ps1 | 1 + .../01-Deploy-ManagementGroups.ps1 | 30 +++++++++++++++++++ scripts/deployments/02-Deploy-Roles.ps1 | 23 ++++++++++++++ scripts/deployments/03-Deploy-Logging.ps1 | 21 +++++++++++++ 4 files changed, 75 insertions(+) create mode 100644 scripts/deployments/00-Install-Prerequisites.ps1 create mode 100644 scripts/deployments/01-Deploy-ManagementGroups.ps1 create mode 100644 scripts/deployments/02-Deploy-Roles.ps1 create mode 100644 scripts/deployments/03-Deploy-Logging.ps1 diff --git a/scripts/deployments/00-Install-Prerequisites.ps1 b/scripts/deployments/00-Install-Prerequisites.ps1 new file mode 100644 index 00000000..8c34b6a8 --- /dev/null +++ b/scripts/deployments/00-Install-Prerequisites.ps1 @@ -0,0 +1 @@ +Install-Module powershell-yaml -Force diff --git a/scripts/deployments/01-Deploy-ManagementGroups.ps1 b/scripts/deployments/01-Deploy-ManagementGroups.ps1 new file mode 100644 index 00000000..ed481818 --- /dev/null +++ b/scripts/deployments/01-Deploy-ManagementGroups.ps1 @@ -0,0 +1,30 @@ +Import-Module powershell-yaml + +# Configuration +$WorkingDirectory = "../../" +$Environment = "CanadaESLZ-main" +$EnvironmentConfigurationYamlFilePath = "$WorkingDirectory/config/variables/$Environment.yml" + +# Deployment +$EnvironmentConfiguration = Get-Content $EnvironmentConfigurationYamlFilePath | ConvertFrom-Yaml +$ManagementGroupHierarchy = $EnvironmentConfiguration.variables['var-managementgroup-hierarchy'] | ConvertFrom-Json + +function ProcessManagementGroupHierarchy { + param ( + $parentNode + ) + + foreach ($childNode in $parentNode.children) { + $parentManagementGroupId = $parentNode.id + $childManagementGroupId = $childNode.id + $childManagementGroupName = $childNode.name + + Write-Output "Creating $childManagementGroupName [$childManagementGroupId] under $parentManagementGroupId" + + # Add Azure PS deployment command + + ProcessManagementGroupHierarchy($childNode) + } +} + +ProcessManagementGroupHierarchy($ManagementGroupHierarchy) \ No newline at end of file diff --git a/scripts/deployments/02-Deploy-Roles.ps1 b/scripts/deployments/02-Deploy-Roles.ps1 new file mode 100644 index 00000000..6e7bfd72 --- /dev/null +++ b/scripts/deployments/02-Deploy-Roles.ps1 @@ -0,0 +1,23 @@ +Import-Module powershell-yaml + +# Configuration +$WorkingDirectory = "../../" +$Environment = "CanadaESLZ-main" +$EnvironmentConfigurationYamlFilePath = "$WorkingDirectory/config/variables/$Environment.yml" +$RolesDirectory = "$WorkingDirectory/roles" + +# Deployment +$EnvironmentConfiguration = Get-Content $EnvironmentConfigurationYamlFilePath | ConvertFrom-Yaml +$ManagementGroupHierarchy = $EnvironmentConfiguration.variables['var-managementgroup-hierarchy'] | ConvertFrom-Json + +$TopLevelManagementGroup = $ManagementGroupHierarchy.children[0] + +Write-Output "Using top level management group: $($TopLevelManagementGroup.id)" +Write-Output "Deploying role definitions from $RolesDirectory" + +foreach ($roleDefinition in Get-ChildItem -Path $RolesDirectory) { + Write-Output "Deploying $($roleDefinition.name)" + + # Add Azure PS deployment command +} + diff --git a/scripts/deployments/03-Deploy-Logging.ps1 b/scripts/deployments/03-Deploy-Logging.ps1 new file mode 100644 index 00000000..b65ca02b --- /dev/null +++ b/scripts/deployments/03-Deploy-Logging.ps1 @@ -0,0 +1,21 @@ +Import-Module powershell-yaml + +# Configuration +$WorkingDirectory = "../../" +$LoggingDirectory = "$WorkingDirectory/config/logging" +$Environment = "CanadaESLZ-main" +$EnvironmentConfigurationYamlFilePath = "$WorkingDirectory/config/variables/$Environment.yml" + +# Deployment +$EnvironmentConfiguration = Get-Content $EnvironmentConfigurationYamlFilePath | ConvertFrom-Yaml + +$DeploymentRegion = $EnvironmentConfiguration.variables['var-logging-region'] +$DeploymentManagementGroup = $EnvironmentConfiguration.variables['var-logging-managementGroupId'] +$DeploymentSubscription = $EnvironmentConfiguration.variables['var-logging-subscriptionId'] +$DeploymentConfigurationFileName = $EnvironmentConfiguration.variables['var-logging-configurationFileName'] + +Write-Output "Moving Subscription ($DeploymentSubscription) to Management Group ($DeploymentManagementGroup)" +# Add Azure PS deployment command + +Write-Output "Deploying $LoggingDirectory/$DeploymentConfigurationFileName to $DeploymentSubscription in $DeploymentRegion" +# Add Azure PS deployment command \ No newline at end of file From d57270f2a805e013c717a2660426d5e5289076dd Mon Sep 17 00:00:00 2001 From: Senthuran Sivananthan Date: Thu, 28 Apr 2022 11:22:33 -0400 Subject: [PATCH 02/31] Add todo marker --- scripts/deployments/01-Deploy-ManagementGroups.ps1 | 2 +- scripts/deployments/02-Deploy-Roles.ps1 | 2 +- scripts/deployments/03-Deploy-Logging.ps1 | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/deployments/01-Deploy-ManagementGroups.ps1 b/scripts/deployments/01-Deploy-ManagementGroups.ps1 index ed481818..e665b3da 100644 --- a/scripts/deployments/01-Deploy-ManagementGroups.ps1 +++ b/scripts/deployments/01-Deploy-ManagementGroups.ps1 @@ -21,7 +21,7 @@ function ProcessManagementGroupHierarchy { Write-Output "Creating $childManagementGroupName [$childManagementGroupId] under $parentManagementGroupId" - # Add Azure PS deployment command + # TODO: Add Azure PS deployment command ProcessManagementGroupHierarchy($childNode) } diff --git a/scripts/deployments/02-Deploy-Roles.ps1 b/scripts/deployments/02-Deploy-Roles.ps1 index 6e7bfd72..a7d2316c 100644 --- a/scripts/deployments/02-Deploy-Roles.ps1 +++ b/scripts/deployments/02-Deploy-Roles.ps1 @@ -18,6 +18,6 @@ Write-Output "Deploying role definitions from $RolesDirectory" foreach ($roleDefinition in Get-ChildItem -Path $RolesDirectory) { Write-Output "Deploying $($roleDefinition.name)" - # Add Azure PS deployment command + # TODO: Add Azure PS deployment command } diff --git a/scripts/deployments/03-Deploy-Logging.ps1 b/scripts/deployments/03-Deploy-Logging.ps1 index b65ca02b..e8d18e14 100644 --- a/scripts/deployments/03-Deploy-Logging.ps1 +++ b/scripts/deployments/03-Deploy-Logging.ps1 @@ -15,7 +15,7 @@ $DeploymentSubscription = $EnvironmentConfiguration.variables['var-logging-subsc $DeploymentConfigurationFileName = $EnvironmentConfiguration.variables['var-logging-configurationFileName'] Write-Output "Moving Subscription ($DeploymentSubscription) to Management Group ($DeploymentManagementGroup)" -# Add Azure PS deployment command +# TODO: Add Azure PS deployment command Write-Output "Deploying $LoggingDirectory/$DeploymentConfigurationFileName to $DeploymentSubscription in $DeploymentRegion" -# Add Azure PS deployment command \ No newline at end of file +# TODO: Add Azure PS deployment command \ No newline at end of file From 77560c726fbac987bc48ab514178c21fb057c5ec Mon Sep 17 00:00:00 2001 From: Senthuran Sivananthan Date: Thu, 28 Apr 2022 11:41:37 -0400 Subject: [PATCH 03/31] Update config path --- scripts/deployments/03-Deploy-Logging.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/deployments/03-Deploy-Logging.ps1 b/scripts/deployments/03-Deploy-Logging.ps1 index e8d18e14..d443e221 100644 --- a/scripts/deployments/03-Deploy-Logging.ps1 +++ b/scripts/deployments/03-Deploy-Logging.ps1 @@ -2,8 +2,8 @@ Import-Module powershell-yaml # Configuration $WorkingDirectory = "../../" -$LoggingDirectory = "$WorkingDirectory/config/logging" $Environment = "CanadaESLZ-main" +$LoggingDirectory = "$WorkingDirectory/config/logging/$Environment/" $EnvironmentConfigurationYamlFilePath = "$WorkingDirectory/config/variables/$Environment.yml" # Deployment From 761e0e250f7d5c2d6bf774306c1ea1a99e30fdf7 Mon Sep 17 00:00:00 2001 From: Senthuran Sivananthan Date: Thu, 28 Apr 2022 11:41:54 -0400 Subject: [PATCH 04/31] Scaffolding for Policy --- scripts/deployments/04-Deploy-Policy.ps1 | 170 +++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 scripts/deployments/04-Deploy-Policy.ps1 diff --git a/scripts/deployments/04-Deploy-Policy.ps1 b/scripts/deployments/04-Deploy-Policy.ps1 new file mode 100644 index 00000000..75d2afa9 --- /dev/null +++ b/scripts/deployments/04-Deploy-Policy.ps1 @@ -0,0 +1,170 @@ +Import-Module powershell-yaml + +# Configuration +$WorkingDirectory = "../../" +$Environment = "CanadaESLZ-main" +$EnvironmentConfigurationYamlFilePath = "$WorkingDirectory/config/variables/$Environment.yml" + +$LoggingDirectory = "$WorkingDirectory/config/logging/$Environment/" +$PolicyRootDirectory = "$WorkingDirectory/policy" + +$EnvironmentConfiguration = Get-Content $EnvironmentConfigurationYamlFilePath | ConvertFrom-Yaml +$ManagementGroupHierarchy = $EnvironmentConfiguration.variables['var-managementgroup-hierarchy'] | ConvertFrom-Json +$TopLevelManagementGroup = $ManagementGroupHierarchy.children[0] + +$LoggingSubscription = $EnvironmentConfiguration.variables['var-logging-subscriptionId'] +$LoggingConfigurationFileName = $EnvironmentConfiguration.variables['var-logging-configurationFileName'] + +$BuiltInPolicySetAssignmentScopes = $( + [PSCustomObject]@{ + ManagementGroupId = $TopLevelManagementGroup.id + Policies = $( + 'asb', + 'nist80053r4', + 'nist80053r5', + 'pbmm', + 'cis-msft-130', + 'fedramp-moderate', + 'hitrust-hipaa', + 'location' + ) + LoggingSubscriptionId = $LoggingSubscription + LoggingConfigurationFilePath = "$LoggingDirectory/$LoggingConfigurationFileName" + } +) + +$CustomPolicySetDefinitions = $( + 'AKS', + 'DefenderForCloud', + 'LogAnalytics', + 'Network', + 'DNSPrivateEndpoints', + 'Tags' +) + +$CustomPolicySetAssignmentScopes = $( + [PSCustomObject]@{ + ManagementGroupId = $TopLevelManagementGroup.id + Policies = $( + 'AKS', + 'DefenderForCloud', + 'LogAnalytics', + 'Network', + 'Tags' + ) + LoggingSubscriptionId = $LoggingSubscription + LoggingConfigurationFilePath = "$LoggingDirectory/$LoggingConfigurationFileName" + } +) + +# Deployment + +# Enumerate and deploy built-in policy assignments +$BuiltInPolicySetAssignmentsDirectory = "$PolicyRootDirectory/builtin/assignments" + +foreach ($assignmentScope in $BuiltInPolicySetAssignmentScopes) { + Write-Output "Assignment scope: $($assignmentScope.ManagementGroupId)" + Write-Output "Logging Subscription: $($assignmentScope.LoggingSubscriptionId)" + Write-Output "Logging Configuration: $($assignmentScope.LoggingConfigurationFilePath)" + + foreach ($policy in $assignmentScope.Policies) { + Write-Output "Policy: $policy" + + $DefaultPolicyParameterFilePath = "$BuiltInPolicySetAssignmentsDirectory/$policy.parameters.json" + $AssignmentScopeParameterFilePath = "$BuiltInPolicySetAssignmentsDirectory/$policy-$($assignmentScope.ManagementGroupId).parameters.json" + + # Check if there is an assignment scope specific parameter file. + # The file will have the syntax -.parameters.json + # If not found, then use the default parameter file with syntax .parameters.json + if (Test-Path $AssignmentScopeParameterFilePath -PathType Leaf) { + $PolicyParameterFilePath = $AssignmentScopeParameterFilePath + } else { + $PolicyParameterFilePath = $DefaultPolicyParameterFilePath + } + + Write-Output "Policy: $policy" + Write-Output "- Definition: $BuiltInPolicySetAssignmentsDirectory/$policy.bicep" + Write-Output "- Parameters: $PolicyParameterFilePath" + + # TODO: Add logic to replace templated parameters + + # TODO: Add Azure PS deployment command + + } +} + +# Enumerate and deploy the custom policy definitions +$CustomPolicyDefinitionDirectory = "$PolicyRootDirectory/custom/definitions/policy" + +Get-ChildItem -Directory -Path $CustomPolicyDefinitionDirectory | + Foreach-Object { + $PolicyDefinitionName = $_.Name + $PolicyConfigFilePath = "$($_.FullName)/azurepolicy.config.json" + $PolicyRuleFilePath = "$($_.FullName)/azurepolicy.rules.json" + $PolicyParametersFilePath = "$($_.FullName)/azurepolicy.parameters.json" + + Write-Output "Policy: $PolicyDefinitionName" + Write-Output "- Rule: $PolicyRuleFilePath" + Write-Output "- Parameters: $PolicyParametersFilePath" + Write-Output "- Config: $PolicyConfigFilePath" + + # TODO: Add Azure PS deployment command + } + +# Enumerate and deploy custom policy set definitions +$CustomPolicySetDefinitionsDirectory = "$PolicyRootDirectory/custom/definitions/policyset" + +foreach ($policySetDefinitionName in $CustomPolicySetDefinitions) { + Write-Output "Policy set definition: $policySetDefinitionName" + + $PolicySetDefinitionFilePath = "$($CustomPolicySetDefinitionsDirectory)/$($policySetDefinitionName).bicep" + $PolicySetDefinitionParametersFilePath = "$($CustomPolicySetDefinitionsDirectory)/$($policySetDefinitionName).parameters.json" + + Write-Output "Policy Set: $policySetDefinitionName" + Write-Output "- Definition: $PolicySetDefinitionFilePath" + Write-Output "- Parameters: $PolicySetDefinitionParametersFilePath" + + # TODO: Add logic to load logging configuration + + # TODO: Add logic to replace templated parameters + + # TODO: Add Azure PS deployment command +} + + +# Enumerate and deploy custom policy assignments + +$CustomPolicySetAssignmentsDirectory = "$PolicyRootDirectory/custom/assignments/policyset" + +foreach ($assignmentScope in $CustomPolicySetAssignmentScopes) { + Write-Output "Assignment scope: $($assignmentScope.ManagementGroupId)" + Write-Output "Logging Subscription: $($assignmentScope.LoggingSubscriptionId)" + Write-Output "Logging Configuration: $($assignmentScope.LoggingConfigurationFilePath)" + + foreach ($policy in $assignmentScope.Policies) { + Write-Output "Policy: $policy" + + $DefaultPolicyParameterFilePath = "$CustomPolicySetAssignmentsDirectory/$policy.parameters.json" + $AssignmentScopeParameterFilePath = "$CustomPolicySetAssignmentsDirectory/$policy-$($assignmentScope.ManagementGroupId).parameters.json" + + # Check if there is an assignment scope specific parameter file. + # The file will have the syntax -.parameters.json + # If not found, then use the default parameter file with syntax .parameters.json + if (Test-Path $AssignmentScopeParameterFilePath -PathType Leaf) { + $PolicyParameterFilePath = $AssignmentScopeParameterFilePath + } else { + $PolicyParameterFilePath = $DefaultPolicyParameterFilePath + } + + Write-Output "Policy: $policy" + Write-Output "- Definition: $CustomPolicySetAssignmentsDirectory/$policy.bicep" + Write-Output "- Parameters: $PolicyParameterFilePath" + + # TODO: Add logic to load logging configuration + + # TODO: Add logic to replace templated parameters + + # TODO: Add Azure PS deployment command + + } +} \ No newline at end of file From c968bceb7989bd8c87c6c1ff02fdae26b6a530a5 Mon Sep 17 00:00:00 2001 From: Senthuran Sivananthan Date: Thu, 28 Apr 2022 11:50:57 -0400 Subject: [PATCH 05/31] Scaffolding for Hub with NVA --- .../deployments/05-Deploy-Hub-With-NVA.ps1 | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 scripts/deployments/05-Deploy-Hub-With-NVA.ps1 diff --git a/scripts/deployments/05-Deploy-Hub-With-NVA.ps1 b/scripts/deployments/05-Deploy-Hub-With-NVA.ps1 new file mode 100644 index 00000000..636dee4d --- /dev/null +++ b/scripts/deployments/05-Deploy-Hub-With-NVA.ps1 @@ -0,0 +1,28 @@ +Import-Module powershell-yaml + +# Configuration +$WorkingDirectory = "../../" +$Environment = "CanadaESLZ-main" + +$LoggingDirectory = "$WorkingDirectory/config/logging/$Environment/" +$NetworkingDirectory = "$WorkingDirectory/config/logging/$Environment/" + +$EnvironmentConfigurationYamlFilePath = "$WorkingDirectory/config/variables/$Environment.yml" + +# Deployment +$EnvironmentConfiguration = Get-Content $EnvironmentConfigurationYamlFilePath | ConvertFrom-Yaml + +$DeploymentRegion = $EnvironmentConfiguration.variables['var-hubnetwork-region'] +$DeploymentManagementGroup = $EnvironmentConfiguration.variables['var-hubnetwork-managementGroupId'] +$DeploymentSubscription = $EnvironmentConfiguration.variables['var-hubnetwork-subscriptionId'] +$DeploymentConfigurationFileName = $EnvironmentConfiguration.variables['var-hubnetwork-nva-configurationFileName'] + +$LoggingSubscription = $EnvironmentConfiguration.variables['var-logging-subscriptionId'] +$LoggingConfigurationFileName = $EnvironmentConfiguration.variables['var-logging-configurationFileName'] +$LoggingConfigurationFilePath = "$LoggingDirectory/$LoggingConfigurationFileName" + +# TODO: Load logging configuration + +# TODO: Load networking configuration and check if Log Analytics Workspace Id is provided. Otherwise set it. + +# TODO: Add Azure PS deployment command \ No newline at end of file From e1f8b1bc101cd676be5d7e88e70b04ad7f0adc9f Mon Sep 17 00:00:00 2001 From: Senthuran Sivananthan Date: Thu, 28 Apr 2022 11:53:18 -0400 Subject: [PATCH 06/31] Add subscription move step --- scripts/deployments/05-Deploy-Hub-With-NVA.ps1 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/deployments/05-Deploy-Hub-With-NVA.ps1 b/scripts/deployments/05-Deploy-Hub-With-NVA.ps1 index 636dee4d..191f1886 100644 --- a/scripts/deployments/05-Deploy-Hub-With-NVA.ps1 +++ b/scripts/deployments/05-Deploy-Hub-With-NVA.ps1 @@ -25,4 +25,8 @@ $LoggingConfigurationFilePath = "$LoggingDirectory/$LoggingConfigurationFileName # TODO: Load networking configuration and check if Log Analytics Workspace Id is provided. Otherwise set it. +Write-Output "Moving Subscription ($DeploymentSubscription) to Management Group ($DeploymentManagementGroup)" +# TODO: Add Azure PS deployment command + +Write-Output "Deploying $NetworkingDirectory/$DeploymentConfigurationFileName to $DeploymentSubscription in $DeploymentRegion" # TODO: Add Azure PS deployment command \ No newline at end of file From eebddc30527085c2811aaa0920b73e5a668a29c9 Mon Sep 17 00:00:00 2001 From: Senthuran Sivananthan Date: Thu, 28 Apr 2022 11:59:13 -0400 Subject: [PATCH 07/31] Fix path --- scripts/deployments/05-Deploy-Hub-With-NVA.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/deployments/05-Deploy-Hub-With-NVA.ps1 b/scripts/deployments/05-Deploy-Hub-With-NVA.ps1 index 191f1886..61857ea1 100644 --- a/scripts/deployments/05-Deploy-Hub-With-NVA.ps1 +++ b/scripts/deployments/05-Deploy-Hub-With-NVA.ps1 @@ -5,7 +5,7 @@ $WorkingDirectory = "../../" $Environment = "CanadaESLZ-main" $LoggingDirectory = "$WorkingDirectory/config/logging/$Environment/" -$NetworkingDirectory = "$WorkingDirectory/config/logging/$Environment/" +$NetworkingDirectory = "$WorkingDirectory/config/networking/$Environment/" $EnvironmentConfigurationYamlFilePath = "$WorkingDirectory/config/variables/$Environment.yml" From d8441227f921b07b840ef45836d7a9759343533b Mon Sep 17 00:00:00 2001 From: Senthuran Sivananthan Date: Thu, 28 Apr 2022 12:01:00 -0400 Subject: [PATCH 08/31] Scaffolding for deploying AzFW Policy --- ...a-Deploy-Hub-With-AzFW-Firewall-Policy.ps1 | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 scripts/deployments/06a-Deploy-Hub-With-AzFW-Firewall-Policy.ps1 diff --git a/scripts/deployments/06a-Deploy-Hub-With-AzFW-Firewall-Policy.ps1 b/scripts/deployments/06a-Deploy-Hub-With-AzFW-Firewall-Policy.ps1 new file mode 100644 index 00000000..c6e429c6 --- /dev/null +++ b/scripts/deployments/06a-Deploy-Hub-With-AzFW-Firewall-Policy.ps1 @@ -0,0 +1,19 @@ +Import-Module powershell-yaml + +# Configuration +$WorkingDirectory = "../../" +$Environment = "CanadaESLZ-main" + +$NetworkingDirectory = "$WorkingDirectory/config/networking/$Environment/" + +$EnvironmentConfigurationYamlFilePath = "$WorkingDirectory/config/variables/$Environment.yml" + +# Deployment +$EnvironmentConfiguration = Get-Content $EnvironmentConfigurationYamlFilePath | ConvertFrom-Yaml + +$DeploymentRegion = $EnvironmentConfiguration.variables['var-hubnetwork-region'] +$DeploymentSubscription = $EnvironmentConfiguration.variables['var-hubnetwork-subscriptionId'] +$DeploymentConfigurationFileName = $EnvironmentConfiguration.variables['var-hubnetwork-azfwPolicy-configurationFileName'] + +Write-Output "Deploying $NetworkingDirectory/$DeploymentConfigurationFileName to $DeploymentSubscription in $DeploymentRegion" +# TODO: Add Azure PS deployment command \ No newline at end of file From cc8a3ea0dda97cdbb3f587fbc0fac16007a3f654 Mon Sep 17 00:00:00 2001 From: Senthuran Sivananthan Date: Thu, 28 Apr 2022 12:04:50 -0400 Subject: [PATCH 09/31] Scaffolding for Hub + AzFW --- .../06b-Deploy-Hub-With-AzFW-Firewall.ps1 | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 scripts/deployments/06b-Deploy-Hub-With-AzFW-Firewall.ps1 diff --git a/scripts/deployments/06b-Deploy-Hub-With-AzFW-Firewall.ps1 b/scripts/deployments/06b-Deploy-Hub-With-AzFW-Firewall.ps1 new file mode 100644 index 00000000..d168c5ab --- /dev/null +++ b/scripts/deployments/06b-Deploy-Hub-With-AzFW-Firewall.ps1 @@ -0,0 +1,36 @@ +Import-Module powershell-yaml + +# Configuration +$WorkingDirectory = "../../" +$Environment = "CanadaESLZ-main" + +$LoggingDirectory = "$WorkingDirectory/config/logging/$Environment/" +$NetworkingDirectory = "$WorkingDirectory/config/networking/$Environment/" + +$EnvironmentConfigurationYamlFilePath = "$WorkingDirectory/config/variables/$Environment.yml" + +$EnvironmentConfiguration = Get-Content $EnvironmentConfigurationYamlFilePath | ConvertFrom-Yaml + +$LoggingSubscription = $EnvironmentConfiguration.variables['var-logging-subscriptionId'] +$LoggingConfigurationFileName = $EnvironmentConfiguration.variables['var-logging-configurationFileName'] +$LoggingConfigurationFilePath = "$LoggingDirectory/$LoggingConfigurationFileName" + +$DeploymentRegion = $EnvironmentConfiguration.variables['var-hubnetwork-region'] +$DeploymentManagementGroup = $EnvironmentConfiguration.variables['var-hubnetwork-managementGroupId'] +$DeploymentSubscription = $EnvironmentConfiguration.variables['var-hubnetwork-subscriptionId'] +$DeploymentConfigurationFileName = $EnvironmentConfiguration.variables['var-hubnetwork-azfw-configurationFileName'] +$FirewallPolicyConfigurationFileName = $EnvironmentConfiguration.variables['var-hubnetwork-azfwPolicy-configurationFileName'] + +# Deployment + +# TODO: Load logging configuration + +# TODO: Load networking configuration and check if Log Analytics Workspace Id is provided. Otherwise set it. + +# TODO: Load networking configuration and check if Firewall Policy is provided. Otherwise set it. + +Write-Output "Moving Subscription ($DeploymentSubscription) to Management Group ($DeploymentManagementGroup)" +# TODO: Add Azure PS deployment command + +Write-Output "Deploying $NetworkingDirectory/$DeploymentConfigurationFileName to $DeploymentSubscription in $DeploymentRegion" +# TODO: Add Azure PS deployment command \ No newline at end of file From 3d32bbc182ab266f16dd455ade5551d343a92427 Mon Sep 17 00:00:00 2001 From: Senthuran Sivananthan Date: Thu, 28 Apr 2022 13:30:27 -0400 Subject: [PATCH 10/31] Refactor: Set environment context to preload configuration as global vars --- .../01-Deploy-ManagementGroups.ps1 | 16 +++---- scripts/deployments/02-Deploy-Roles.ps1 | 21 ++++---- scripts/deployments/03-Deploy-Logging.ps1 | 24 +++++----- scripts/deployments/04-Deploy-Policy.ps1 | 48 +++++++++---------- .../deployments/05-Deploy-Hub-With-NVA.ps1 | 31 +++++------- ...a-Deploy-Hub-With-AzFW-Firewall-Policy.ps1 | 22 ++++----- .../06b-Deploy-Hub-With-AzFW-Firewall.ps1 | 33 ++++++------- .../helpers/Set-EnvironmentContext.ps1 | 17 +++++++ 8 files changed, 102 insertions(+), 110 deletions(-) create mode 100644 scripts/deployments/helpers/Set-EnvironmentContext.ps1 diff --git a/scripts/deployments/01-Deploy-ManagementGroups.ps1 b/scripts/deployments/01-Deploy-ManagementGroups.ps1 index e665b3da..d3eff6e8 100644 --- a/scripts/deployments/01-Deploy-ManagementGroups.ps1 +++ b/scripts/deployments/01-Deploy-ManagementGroups.ps1 @@ -1,14 +1,12 @@ -Import-Module powershell-yaml +. ".\helpers\Set-EnvironmentContext.ps1" -# Configuration -$WorkingDirectory = "../../" -$Environment = "CanadaESLZ-main" -$EnvironmentConfigurationYamlFilePath = "$WorkingDirectory/config/variables/$Environment.yml" +# Working Directory +$WorkingDirectory = "../.." -# Deployment -$EnvironmentConfiguration = Get-Content $EnvironmentConfigurationYamlFilePath | ConvertFrom-Yaml -$ManagementGroupHierarchy = $EnvironmentConfiguration.variables['var-managementgroup-hierarchy'] | ConvertFrom-Json +# Set Context +Set-EnvironmentContext -Environment "CanadaESLZ-main" -WorkingDirectory $WorkingDirectory +# Deployment function ProcessManagementGroupHierarchy { param ( $parentNode @@ -27,4 +25,4 @@ function ProcessManagementGroupHierarchy { } } -ProcessManagementGroupHierarchy($ManagementGroupHierarchy) \ No newline at end of file +ProcessManagementGroupHierarchy($global:ManagementGroupHierarchy) \ No newline at end of file diff --git a/scripts/deployments/02-Deploy-Roles.ps1 b/scripts/deployments/02-Deploy-Roles.ps1 index a7d2316c..c84c51e1 100644 --- a/scripts/deployments/02-Deploy-Roles.ps1 +++ b/scripts/deployments/02-Deploy-Roles.ps1 @@ -1,23 +1,18 @@ -Import-Module powershell-yaml +. ".\helpers\Set-EnvironmentContext.ps1" -# Configuration -$WorkingDirectory = "../../" -$Environment = "CanadaESLZ-main" -$EnvironmentConfigurationYamlFilePath = "$WorkingDirectory/config/variables/$Environment.yml" +# Working Directory +$WorkingDirectory = "../.." $RolesDirectory = "$WorkingDirectory/roles" -# Deployment -$EnvironmentConfiguration = Get-Content $EnvironmentConfigurationYamlFilePath | ConvertFrom-Yaml -$ManagementGroupHierarchy = $EnvironmentConfiguration.variables['var-managementgroup-hierarchy'] | ConvertFrom-Json - -$TopLevelManagementGroup = $ManagementGroupHierarchy.children[0] +# Set Context +Set-EnvironmentContext -Environment "CanadaESLZ-main" -WorkingDirectory $WorkingDirectory -Write-Output "Using top level management group: $($TopLevelManagementGroup.id)" -Write-Output "Deploying role definitions from $RolesDirectory" +# Deployment +Write-Output "Using top level management group: $global:TopLevelManagementGroupId" +Write-Output "Deploying role definitions from $global:RolesDirectory" foreach ($roleDefinition in Get-ChildItem -Path $RolesDirectory) { Write-Output "Deploying $($roleDefinition.name)" # TODO: Add Azure PS deployment command } - diff --git a/scripts/deployments/03-Deploy-Logging.ps1 b/scripts/deployments/03-Deploy-Logging.ps1 index d443e221..8eccb47b 100644 --- a/scripts/deployments/03-Deploy-Logging.ps1 +++ b/scripts/deployments/03-Deploy-Logging.ps1 @@ -1,21 +1,19 @@ -Import-Module powershell-yaml +. ".\helpers\Set-EnvironmentContext.ps1" -# Configuration -$WorkingDirectory = "../../" -$Environment = "CanadaESLZ-main" -$LoggingDirectory = "$WorkingDirectory/config/logging/$Environment/" -$EnvironmentConfigurationYamlFilePath = "$WorkingDirectory/config/variables/$Environment.yml" +# Working Directory +$WorkingDirectory = "../.." -# Deployment -$EnvironmentConfiguration = Get-Content $EnvironmentConfigurationYamlFilePath | ConvertFrom-Yaml +# Set Context +Set-EnvironmentContext -Environment "CanadaESLZ-main" -WorkingDirectory $WorkingDirectory -$DeploymentRegion = $EnvironmentConfiguration.variables['var-logging-region'] -$DeploymentManagementGroup = $EnvironmentConfiguration.variables['var-logging-managementGroupId'] -$DeploymentSubscription = $EnvironmentConfiguration.variables['var-logging-subscriptionId'] -$DeploymentConfigurationFileName = $EnvironmentConfiguration.variables['var-logging-configurationFileName'] +# Deployment +$DeploymentRegion = $global:EnvironmentConfiguration.variables['var-logging-region'] +$DeploymentManagementGroup = $global:EnvironmentConfiguration.variables['var-logging-managementGroupId'] +$DeploymentSubscription = $global:EnvironmentConfiguration.variables['var-logging-subscriptionId'] +$DeploymentConfigurationFileName = $global:EnvironmentConfiguration.variables['var-logging-configurationFileName'] Write-Output "Moving Subscription ($DeploymentSubscription) to Management Group ($DeploymentManagementGroup)" # TODO: Add Azure PS deployment command -Write-Output "Deploying $LoggingDirectory/$DeploymentConfigurationFileName to $DeploymentSubscription in $DeploymentRegion" +Write-Output "Deploying $global:LoggingDirectory/$DeploymentConfigurationFileName to $DeploymentSubscription in $DeploymentRegion" # TODO: Add Azure PS deployment command \ No newline at end of file diff --git a/scripts/deployments/04-Deploy-Policy.ps1 b/scripts/deployments/04-Deploy-Policy.ps1 index 75d2afa9..281590f9 100644 --- a/scripts/deployments/04-Deploy-Policy.ps1 +++ b/scripts/deployments/04-Deploy-Policy.ps1 @@ -1,23 +1,20 @@ -Import-Module powershell-yaml +. ".\helpers\Set-EnvironmentContext.ps1" -# Configuration -$WorkingDirectory = "../../" -$Environment = "CanadaESLZ-main" -$EnvironmentConfigurationYamlFilePath = "$WorkingDirectory/config/variables/$Environment.yml" +# Working Directory +$WorkingDirectory = "../.." -$LoggingDirectory = "$WorkingDirectory/config/logging/$Environment/" -$PolicyRootDirectory = "$WorkingDirectory/policy" +# Set Context +Set-EnvironmentContext -Environment "CanadaESLZ-main" -WorkingDirectory $WorkingDirectory -$EnvironmentConfiguration = Get-Content $EnvironmentConfigurationYamlFilePath | ConvertFrom-Yaml -$ManagementGroupHierarchy = $EnvironmentConfiguration.variables['var-managementgroup-hierarchy'] | ConvertFrom-Json -$TopLevelManagementGroup = $ManagementGroupHierarchy.children[0] +$PolicyRootDirectory = "$WorkingDirectory/policy" -$LoggingSubscription = $EnvironmentConfiguration.variables['var-logging-subscriptionId'] -$LoggingConfigurationFileName = $EnvironmentConfiguration.variables['var-logging-configurationFileName'] +$LoggingSubscription = $global:EnvironmentConfiguration.variables['var-logging-subscriptionId'] +$LoggingConfigurationFileName = $global:EnvironmentConfiguration.variables['var-logging-configurationFileName'] +#region Policy definition & assignment configuration $BuiltInPolicySetAssignmentScopes = $( [PSCustomObject]@{ - ManagementGroupId = $TopLevelManagementGroup.id + ManagementGroupId = $global:TopLevelManagementGroupId Policies = $( 'asb', 'nist80053r4', @@ -29,7 +26,7 @@ $BuiltInPolicySetAssignmentScopes = $( 'location' ) LoggingSubscriptionId = $LoggingSubscription - LoggingConfigurationFilePath = "$LoggingDirectory/$LoggingConfigurationFileName" + LoggingConfigurationFilePath = "$global:LoggingDirectory/$LoggingConfigurationFileName" } ) @@ -44,7 +41,7 @@ $CustomPolicySetDefinitions = $( $CustomPolicySetAssignmentScopes = $( [PSCustomObject]@{ - ManagementGroupId = $TopLevelManagementGroup.id + ManagementGroupId = $global:TopLevelManagementGroupId Policies = $( 'AKS', 'DefenderForCloud', @@ -53,13 +50,12 @@ $CustomPolicySetAssignmentScopes = $( 'Tags' ) LoggingSubscriptionId = $LoggingSubscription - LoggingConfigurationFilePath = "$LoggingDirectory/$LoggingConfigurationFileName" + LoggingConfigurationFilePath = "$global:LoggingDirectory/$LoggingConfigurationFileName" } ) +#endregion -# Deployment - -# Enumerate and deploy built-in policy assignments +#region Enumerate and deploy built-in policy assignments $BuiltInPolicySetAssignmentsDirectory = "$PolicyRootDirectory/builtin/assignments" foreach ($assignmentScope in $BuiltInPolicySetAssignmentScopes) { @@ -92,8 +88,9 @@ foreach ($assignmentScope in $BuiltInPolicySetAssignmentScopes) { } } +#endregion -# Enumerate and deploy the custom policy definitions +#region Enumerate and deploy the custom policy definitions $CustomPolicyDefinitionDirectory = "$PolicyRootDirectory/custom/definitions/policy" Get-ChildItem -Directory -Path $CustomPolicyDefinitionDirectory | @@ -110,8 +107,9 @@ Get-ChildItem -Directory -Path $CustomPolicyDefinitionDirectory | # TODO: Add Azure PS deployment command } +#endregion -# Enumerate and deploy custom policy set definitions +#region Enumerate and deploy custom policy set definitions $CustomPolicySetDefinitionsDirectory = "$PolicyRootDirectory/custom/definitions/policyset" foreach ($policySetDefinitionName in $CustomPolicySetDefinitions) { @@ -130,10 +128,9 @@ foreach ($policySetDefinitionName in $CustomPolicySetDefinitions) { # TODO: Add Azure PS deployment command } +#endregion - -# Enumerate and deploy custom policy assignments - +#region Enumerate and deploy custom policy assignments $CustomPolicySetAssignmentsDirectory = "$PolicyRootDirectory/custom/assignments/policyset" foreach ($assignmentScope in $CustomPolicySetAssignmentScopes) { @@ -167,4 +164,5 @@ foreach ($assignmentScope in $CustomPolicySetAssignmentScopes) { # TODO: Add Azure PS deployment command } -} \ No newline at end of file +} +#endregion \ No newline at end of file diff --git a/scripts/deployments/05-Deploy-Hub-With-NVA.ps1 b/scripts/deployments/05-Deploy-Hub-With-NVA.ps1 index 61857ea1..c2b999eb 100644 --- a/scripts/deployments/05-Deploy-Hub-With-NVA.ps1 +++ b/scripts/deployments/05-Deploy-Hub-With-NVA.ps1 @@ -1,25 +1,20 @@ -Import-Module powershell-yaml +. ".\helpers\Set-EnvironmentContext.ps1" -# Configuration -$WorkingDirectory = "../../" -$Environment = "CanadaESLZ-main" +# Working Directory +$WorkingDirectory = "../.." -$LoggingDirectory = "$WorkingDirectory/config/logging/$Environment/" -$NetworkingDirectory = "$WorkingDirectory/config/networking/$Environment/" - -$EnvironmentConfigurationYamlFilePath = "$WorkingDirectory/config/variables/$Environment.yml" +# Set Context +Set-EnvironmentContext -Environment "CanadaESLZ-main" -WorkingDirectory $WorkingDirectory # Deployment -$EnvironmentConfiguration = Get-Content $EnvironmentConfigurationYamlFilePath | ConvertFrom-Yaml - -$DeploymentRegion = $EnvironmentConfiguration.variables['var-hubnetwork-region'] -$DeploymentManagementGroup = $EnvironmentConfiguration.variables['var-hubnetwork-managementGroupId'] -$DeploymentSubscription = $EnvironmentConfiguration.variables['var-hubnetwork-subscriptionId'] -$DeploymentConfigurationFileName = $EnvironmentConfiguration.variables['var-hubnetwork-nva-configurationFileName'] +$DeploymentRegion = $global:EnvironmentConfiguration.variables['var-hubnetwork-region'] +$DeploymentManagementGroup = $global:EnvironmentConfiguration.variables['var-hubnetwork-managementGroupId'] +$DeploymentSubscription = $global:EnvironmentConfiguration.variables['var-hubnetwork-subscriptionId'] +$DeploymentConfigurationFileName = $global:EnvironmentConfiguration.variables['var-hubnetwork-nva-configurationFileName'] -$LoggingSubscription = $EnvironmentConfiguration.variables['var-logging-subscriptionId'] -$LoggingConfigurationFileName = $EnvironmentConfiguration.variables['var-logging-configurationFileName'] -$LoggingConfigurationFilePath = "$LoggingDirectory/$LoggingConfigurationFileName" +$LoggingSubscription = $global:EnvironmentConfiguration.variables['var-logging-subscriptionId'] +$LoggingConfigurationFileName = $global:EnvironmentConfiguration.variables['var-logging-configurationFileName'] +$LoggingConfigurationFilePath = "$global:LoggingDirectory/$LoggingConfigurationFileName" # TODO: Load logging configuration @@ -28,5 +23,5 @@ $LoggingConfigurationFilePath = "$LoggingDirectory/$LoggingConfigurationFileName Write-Output "Moving Subscription ($DeploymentSubscription) to Management Group ($DeploymentManagementGroup)" # TODO: Add Azure PS deployment command -Write-Output "Deploying $NetworkingDirectory/$DeploymentConfigurationFileName to $DeploymentSubscription in $DeploymentRegion" +Write-Output "Deploying $global:NetworkingDirectory/$DeploymentConfigurationFileName to $DeploymentSubscription in $DeploymentRegion" # TODO: Add Azure PS deployment command \ No newline at end of file diff --git a/scripts/deployments/06a-Deploy-Hub-With-AzFW-Firewall-Policy.ps1 b/scripts/deployments/06a-Deploy-Hub-With-AzFW-Firewall-Policy.ps1 index c6e429c6..300907cf 100644 --- a/scripts/deployments/06a-Deploy-Hub-With-AzFW-Firewall-Policy.ps1 +++ b/scripts/deployments/06a-Deploy-Hub-With-AzFW-Firewall-Policy.ps1 @@ -1,19 +1,15 @@ -Import-Module powershell-yaml +. ".\helpers\Set-EnvironmentContext.ps1" -# Configuration -$WorkingDirectory = "../../" -$Environment = "CanadaESLZ-main" +# Working Directory +$WorkingDirectory = "../.." -$NetworkingDirectory = "$WorkingDirectory/config/networking/$Environment/" - -$EnvironmentConfigurationYamlFilePath = "$WorkingDirectory/config/variables/$Environment.yml" +# Set Context +Set-EnvironmentContext -Environment "CanadaESLZ-main" -WorkingDirectory $WorkingDirectory # Deployment -$EnvironmentConfiguration = Get-Content $EnvironmentConfigurationYamlFilePath | ConvertFrom-Yaml - -$DeploymentRegion = $EnvironmentConfiguration.variables['var-hubnetwork-region'] -$DeploymentSubscription = $EnvironmentConfiguration.variables['var-hubnetwork-subscriptionId'] -$DeploymentConfigurationFileName = $EnvironmentConfiguration.variables['var-hubnetwork-azfwPolicy-configurationFileName'] +$DeploymentRegion = $global:EnvironmentConfiguration.variables['var-hubnetwork-region'] +$DeploymentSubscription = $global:EnvironmentConfiguration.variables['var-hubnetwork-subscriptionId'] +$DeploymentConfigurationFileName = $global:EnvironmentConfiguration.variables['var-hubnetwork-azfwPolicy-configurationFileName'] -Write-Output "Deploying $NetworkingDirectory/$DeploymentConfigurationFileName to $DeploymentSubscription in $DeploymentRegion" +Write-Output "Deploying $global:NetworkingDirectory/$DeploymentConfigurationFileName to $DeploymentSubscription in $DeploymentRegion" # TODO: Add Azure PS deployment command \ No newline at end of file diff --git a/scripts/deployments/06b-Deploy-Hub-With-AzFW-Firewall.ps1 b/scripts/deployments/06b-Deploy-Hub-With-AzFW-Firewall.ps1 index d168c5ab..7a378743 100644 --- a/scripts/deployments/06b-Deploy-Hub-With-AzFW-Firewall.ps1 +++ b/scripts/deployments/06b-Deploy-Hub-With-AzFW-Firewall.ps1 @@ -1,25 +1,20 @@ -Import-Module powershell-yaml +. ".\helpers\Set-EnvironmentContext.ps1" -# Configuration -$WorkingDirectory = "../../" -$Environment = "CanadaESLZ-main" +# Working Directory +$WorkingDirectory = "../.." -$LoggingDirectory = "$WorkingDirectory/config/logging/$Environment/" -$NetworkingDirectory = "$WorkingDirectory/config/networking/$Environment/" +# Set Context +Set-EnvironmentContext -Environment "CanadaESLZ-main" -WorkingDirectory $WorkingDirectory -$EnvironmentConfigurationYamlFilePath = "$WorkingDirectory/config/variables/$Environment.yml" +$LoggingSubscription = $global:EnvironmentConfiguration.variables['var-logging-subscriptionId'] +$LoggingConfigurationFileName = $global:EnvironmentConfiguration.variables['var-logging-configurationFileName'] +$LoggingConfigurationFilePath = "$global:LoggingDirectory/$LoggingConfigurationFileName" -$EnvironmentConfiguration = Get-Content $EnvironmentConfigurationYamlFilePath | ConvertFrom-Yaml - -$LoggingSubscription = $EnvironmentConfiguration.variables['var-logging-subscriptionId'] -$LoggingConfigurationFileName = $EnvironmentConfiguration.variables['var-logging-configurationFileName'] -$LoggingConfigurationFilePath = "$LoggingDirectory/$LoggingConfigurationFileName" - -$DeploymentRegion = $EnvironmentConfiguration.variables['var-hubnetwork-region'] -$DeploymentManagementGroup = $EnvironmentConfiguration.variables['var-hubnetwork-managementGroupId'] -$DeploymentSubscription = $EnvironmentConfiguration.variables['var-hubnetwork-subscriptionId'] -$DeploymentConfigurationFileName = $EnvironmentConfiguration.variables['var-hubnetwork-azfw-configurationFileName'] -$FirewallPolicyConfigurationFileName = $EnvironmentConfiguration.variables['var-hubnetwork-azfwPolicy-configurationFileName'] +$DeploymentRegion = $global:EnvironmentConfiguration.variables['var-hubnetwork-region'] +$DeploymentManagementGroup = $global:EnvironmentConfiguration.variables['var-hubnetwork-managementGroupId'] +$DeploymentSubscription = $global:EnvironmentConfiguration.variables['var-hubnetwork-subscriptionId'] +$DeploymentConfigurationFileName = $global:EnvironmentConfiguration.variables['var-hubnetwork-azfw-configurationFileName'] +$FirewallPolicyConfigurationFileName = $global:EnvironmentConfiguration.variables['var-hubnetwork-azfwPolicy-configurationFileName'] # Deployment @@ -32,5 +27,5 @@ $FirewallPolicyConfigurationFileName = $EnvironmentConfiguration.variables['var- Write-Output "Moving Subscription ($DeploymentSubscription) to Management Group ($DeploymentManagementGroup)" # TODO: Add Azure PS deployment command -Write-Output "Deploying $NetworkingDirectory/$DeploymentConfigurationFileName to $DeploymentSubscription in $DeploymentRegion" +Write-Output "Deploying $global:NetworkingDirectory/$DeploymentConfigurationFileName to $DeploymentSubscription in $DeploymentRegion" # TODO: Add Azure PS deployment command \ No newline at end of file diff --git a/scripts/deployments/helpers/Set-EnvironmentContext.ps1 b/scripts/deployments/helpers/Set-EnvironmentContext.ps1 new file mode 100644 index 00000000..1552b0fa --- /dev/null +++ b/scripts/deployments/helpers/Set-EnvironmentContext.ps1 @@ -0,0 +1,17 @@ +Import-Module powershell-yaml +function Set-EnvironmentContext { + param ( + [string] $WorkingDirectory, + [string] $Environment + ) + + $global:EnvironmentConfigurationYamlFilePath = "$WorkingDirectory/config/variables/$Environment.yml" + + $global:LoggingDirectory = "$WorkingDirectory/config/logging/$Environment" + $global:NetworkingDirectory = "$WorkingDirectory/config/networking/$Environment" + + + $global:EnvironmentConfiguration = Get-Content $EnvironmentConfigurationYamlFilePath | ConvertFrom-Yaml + $global:ManagementGroupHierarchy = $EnvironmentConfiguration.variables['var-managementgroup-hierarchy'] | ConvertFrom-Json + $global:TopLevelManagementGroupId = $ManagementGroupHierarchy.children[0].id +} \ No newline at end of file From cb051b6f4f7540bd0db2562e3ebcd9873668fbac Mon Sep 17 00:00:00 2001 From: Senthuran Sivananthan Date: Thu, 28 Apr 2022 13:43:33 -0400 Subject: [PATCH 11/31] Scaffolding for subscriptions --- .../deployments/07-Deploy-Subscriptions.ps1 | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 scripts/deployments/07-Deploy-Subscriptions.ps1 diff --git a/scripts/deployments/07-Deploy-Subscriptions.ps1 b/scripts/deployments/07-Deploy-Subscriptions.ps1 new file mode 100644 index 00000000..6c46d612 --- /dev/null +++ b/scripts/deployments/07-Deploy-Subscriptions.ps1 @@ -0,0 +1,21 @@ +. ".\helpers\Set-EnvironmentContext.ps1" + +# Working Directory +$WorkingDirectory = "../.." + +# Set Context +Set-EnvironmentContext -Environment "CanadaESLZ-main" -WorkingDirectory $WorkingDirectory + +$Subscriptions = $() + +foreach ($subscription in $subscriptions) { + # TODO: Find the ARM JSON parameters + + # TODO: Ensure there's only 1 parameters file for each subscription + + # TODO: Parse the file name to determine archetype, region and subscription id + + # TODO: Load networking configuration and check if Log Analytics Workspace Id is provided. Otherwise set it. + + # TODO: Add Azure PS deployment command +} \ No newline at end of file From e7bd21b75043214830bdf833001a4b0433386609 Mon Sep 17 00:00:00 2001 From: Senthuran Sivananthan Date: Thu, 28 Apr 2022 13:44:49 -0400 Subject: [PATCH 12/31] Ensure we enable Private DNS Zone & DDOS Standard policy assignments when enabled --- scripts/deployments/05-Deploy-Hub-With-NVA.ps1 | 6 +++++- scripts/deployments/06b-Deploy-Hub-With-AzFW-Firewall.ps1 | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/scripts/deployments/05-Deploy-Hub-With-NVA.ps1 b/scripts/deployments/05-Deploy-Hub-With-NVA.ps1 index c2b999eb..2d51cfab 100644 --- a/scripts/deployments/05-Deploy-Hub-With-NVA.ps1 +++ b/scripts/deployments/05-Deploy-Hub-With-NVA.ps1 @@ -24,4 +24,8 @@ Write-Output "Moving Subscription ($DeploymentSubscription) to Management Group # TODO: Add Azure PS deployment command Write-Output "Deploying $global:NetworkingDirectory/$DeploymentConfigurationFileName to $DeploymentSubscription in $DeploymentRegion" -# TODO: Add Azure PS deployment command \ No newline at end of file +# TODO: Add Azure PS deployment command + +# TODO: Check if Private DNS Zones are managed in the Hub. If so, enable Private DNS Zones policy assignment + +# TODO: Check if DDOS Standard is deployed in the Hub. If so, enable DDOS Standard policy assignment \ No newline at end of file diff --git a/scripts/deployments/06b-Deploy-Hub-With-AzFW-Firewall.ps1 b/scripts/deployments/06b-Deploy-Hub-With-AzFW-Firewall.ps1 index 7a378743..56bc064a 100644 --- a/scripts/deployments/06b-Deploy-Hub-With-AzFW-Firewall.ps1 +++ b/scripts/deployments/06b-Deploy-Hub-With-AzFW-Firewall.ps1 @@ -28,4 +28,8 @@ Write-Output "Moving Subscription ($DeploymentSubscription) to Management Group # TODO: Add Azure PS deployment command Write-Output "Deploying $global:NetworkingDirectory/$DeploymentConfigurationFileName to $DeploymentSubscription in $DeploymentRegion" -# TODO: Add Azure PS deployment command \ No newline at end of file +# TODO: Add Azure PS deployment command + +# TODO: Check if Private DNS Zones are managed in the Hub. If so, enable Private DNS Zones policy assignment + +# TODO: Check if DDOS Standard is deployed in the Hub. If so, enable DDOS Standard policy assignment \ No newline at end of file From 15f532b37f4fef3bc697aa614e0b8edc993f902e Mon Sep 17 00:00:00 2001 From: Senthuran Sivananthan Date: Thu, 28 Apr 2022 13:46:10 -0400 Subject: [PATCH 13/31] Rename folder: helpers -> functions --- scripts/deployments/01-Deploy-ManagementGroups.ps1 | 2 +- scripts/deployments/02-Deploy-Roles.ps1 | 2 +- scripts/deployments/03-Deploy-Logging.ps1 | 2 +- scripts/deployments/04-Deploy-Policy.ps1 | 2 +- scripts/deployments/05-Deploy-Hub-With-NVA.ps1 | 2 +- .../deployments/06a-Deploy-Hub-With-AzFW-Firewall-Policy.ps1 | 2 +- scripts/deployments/06b-Deploy-Hub-With-AzFW-Firewall.ps1 | 2 +- scripts/deployments/07-Deploy-Subscriptions.ps1 | 2 +- .../{helpers => functions}/Set-EnvironmentContext.ps1 | 0 9 files changed, 8 insertions(+), 8 deletions(-) rename scripts/deployments/{helpers => functions}/Set-EnvironmentContext.ps1 (100%) diff --git a/scripts/deployments/01-Deploy-ManagementGroups.ps1 b/scripts/deployments/01-Deploy-ManagementGroups.ps1 index d3eff6e8..cb82bba4 100644 --- a/scripts/deployments/01-Deploy-ManagementGroups.ps1 +++ b/scripts/deployments/01-Deploy-ManagementGroups.ps1 @@ -1,4 +1,4 @@ -. ".\helpers\Set-EnvironmentContext.ps1" +. ".\functions\Set-EnvironmentContext.ps1" # Working Directory $WorkingDirectory = "../.." diff --git a/scripts/deployments/02-Deploy-Roles.ps1 b/scripts/deployments/02-Deploy-Roles.ps1 index c84c51e1..60c84ca5 100644 --- a/scripts/deployments/02-Deploy-Roles.ps1 +++ b/scripts/deployments/02-Deploy-Roles.ps1 @@ -1,4 +1,4 @@ -. ".\helpers\Set-EnvironmentContext.ps1" +. ".\functions\Set-EnvironmentContext.ps1" # Working Directory $WorkingDirectory = "../.." diff --git a/scripts/deployments/03-Deploy-Logging.ps1 b/scripts/deployments/03-Deploy-Logging.ps1 index 8eccb47b..fc808c99 100644 --- a/scripts/deployments/03-Deploy-Logging.ps1 +++ b/scripts/deployments/03-Deploy-Logging.ps1 @@ -1,4 +1,4 @@ -. ".\helpers\Set-EnvironmentContext.ps1" +. ".\functions\Set-EnvironmentContext.ps1" # Working Directory $WorkingDirectory = "../.." diff --git a/scripts/deployments/04-Deploy-Policy.ps1 b/scripts/deployments/04-Deploy-Policy.ps1 index 281590f9..8c795feb 100644 --- a/scripts/deployments/04-Deploy-Policy.ps1 +++ b/scripts/deployments/04-Deploy-Policy.ps1 @@ -1,4 +1,4 @@ -. ".\helpers\Set-EnvironmentContext.ps1" +. ".\functions\Set-EnvironmentContext.ps1" # Working Directory $WorkingDirectory = "../.." diff --git a/scripts/deployments/05-Deploy-Hub-With-NVA.ps1 b/scripts/deployments/05-Deploy-Hub-With-NVA.ps1 index 2d51cfab..a872c2d7 100644 --- a/scripts/deployments/05-Deploy-Hub-With-NVA.ps1 +++ b/scripts/deployments/05-Deploy-Hub-With-NVA.ps1 @@ -1,4 +1,4 @@ -. ".\helpers\Set-EnvironmentContext.ps1" +. ".\functions\Set-EnvironmentContext.ps1" # Working Directory $WorkingDirectory = "../.." diff --git a/scripts/deployments/06a-Deploy-Hub-With-AzFW-Firewall-Policy.ps1 b/scripts/deployments/06a-Deploy-Hub-With-AzFW-Firewall-Policy.ps1 index 300907cf..0ef9734e 100644 --- a/scripts/deployments/06a-Deploy-Hub-With-AzFW-Firewall-Policy.ps1 +++ b/scripts/deployments/06a-Deploy-Hub-With-AzFW-Firewall-Policy.ps1 @@ -1,4 +1,4 @@ -. ".\helpers\Set-EnvironmentContext.ps1" +. ".\functions\Set-EnvironmentContext.ps1" # Working Directory $WorkingDirectory = "../.." diff --git a/scripts/deployments/06b-Deploy-Hub-With-AzFW-Firewall.ps1 b/scripts/deployments/06b-Deploy-Hub-With-AzFW-Firewall.ps1 index 56bc064a..c7ad04b3 100644 --- a/scripts/deployments/06b-Deploy-Hub-With-AzFW-Firewall.ps1 +++ b/scripts/deployments/06b-Deploy-Hub-With-AzFW-Firewall.ps1 @@ -1,4 +1,4 @@ -. ".\helpers\Set-EnvironmentContext.ps1" +. ".\functions\Set-EnvironmentContext.ps1" # Working Directory $WorkingDirectory = "../.." diff --git a/scripts/deployments/07-Deploy-Subscriptions.ps1 b/scripts/deployments/07-Deploy-Subscriptions.ps1 index 6c46d612..3935a3bf 100644 --- a/scripts/deployments/07-Deploy-Subscriptions.ps1 +++ b/scripts/deployments/07-Deploy-Subscriptions.ps1 @@ -1,4 +1,4 @@ -. ".\helpers\Set-EnvironmentContext.ps1" +. ".\functions\Set-EnvironmentContext.ps1" # Working Directory $WorkingDirectory = "../.." diff --git a/scripts/deployments/helpers/Set-EnvironmentContext.ps1 b/scripts/deployments/functions/Set-EnvironmentContext.ps1 similarity index 100% rename from scripts/deployments/helpers/Set-EnvironmentContext.ps1 rename to scripts/deployments/functions/Set-EnvironmentContext.ps1 From 8f97571ceba7527f69c9dadf1215ef6d6b240fe0 Mon Sep 17 00:00:00 2001 From: Senthuran Sivananthan Date: Thu, 28 Apr 2022 14:08:06 -0400 Subject: [PATCH 14/31] Add #requires --- scripts/deployments/01-Deploy-ManagementGroups.ps1 | 2 ++ scripts/deployments/02-Deploy-Roles.ps1 | 2 ++ scripts/deployments/03-Deploy-Logging.ps1 | 2 ++ scripts/deployments/04-Deploy-Policy.ps1 | 2 ++ scripts/deployments/05-Deploy-Hub-With-NVA.ps1 | 2 ++ .../deployments/06a-Deploy-Hub-With-AzFW-Firewall-Policy.ps1 | 2 ++ scripts/deployments/06b-Deploy-Hub-With-AzFW-Firewall.ps1 | 2 ++ scripts/deployments/07-Deploy-Subscriptions.ps1 | 2 ++ scripts/deployments/functions/Set-EnvironmentContext.ps1 | 3 +++ 9 files changed, 19 insertions(+) diff --git a/scripts/deployments/01-Deploy-ManagementGroups.ps1 b/scripts/deployments/01-Deploy-ManagementGroups.ps1 index cb82bba4..88217239 100644 --- a/scripts/deployments/01-Deploy-ManagementGroups.ps1 +++ b/scripts/deployments/01-Deploy-ManagementGroups.ps1 @@ -1,3 +1,5 @@ +#Requires -Modules powershell-yaml + . ".\functions\Set-EnvironmentContext.ps1" # Working Directory diff --git a/scripts/deployments/02-Deploy-Roles.ps1 b/scripts/deployments/02-Deploy-Roles.ps1 index 60c84ca5..d6eb1487 100644 --- a/scripts/deployments/02-Deploy-Roles.ps1 +++ b/scripts/deployments/02-Deploy-Roles.ps1 @@ -1,3 +1,5 @@ +#Requires -Modules powershell-yaml + . ".\functions\Set-EnvironmentContext.ps1" # Working Directory diff --git a/scripts/deployments/03-Deploy-Logging.ps1 b/scripts/deployments/03-Deploy-Logging.ps1 index fc808c99..41fdf550 100644 --- a/scripts/deployments/03-Deploy-Logging.ps1 +++ b/scripts/deployments/03-Deploy-Logging.ps1 @@ -1,3 +1,5 @@ +#Requires -Modules powershell-yaml + . ".\functions\Set-EnvironmentContext.ps1" # Working Directory diff --git a/scripts/deployments/04-Deploy-Policy.ps1 b/scripts/deployments/04-Deploy-Policy.ps1 index 8c795feb..2e4527b8 100644 --- a/scripts/deployments/04-Deploy-Policy.ps1 +++ b/scripts/deployments/04-Deploy-Policy.ps1 @@ -1,3 +1,5 @@ +#Requires -Modules powershell-yaml + . ".\functions\Set-EnvironmentContext.ps1" # Working Directory diff --git a/scripts/deployments/05-Deploy-Hub-With-NVA.ps1 b/scripts/deployments/05-Deploy-Hub-With-NVA.ps1 index a872c2d7..a52e5a1e 100644 --- a/scripts/deployments/05-Deploy-Hub-With-NVA.ps1 +++ b/scripts/deployments/05-Deploy-Hub-With-NVA.ps1 @@ -1,3 +1,5 @@ +#Requires -Modules powershell-yaml + . ".\functions\Set-EnvironmentContext.ps1" # Working Directory diff --git a/scripts/deployments/06a-Deploy-Hub-With-AzFW-Firewall-Policy.ps1 b/scripts/deployments/06a-Deploy-Hub-With-AzFW-Firewall-Policy.ps1 index 0ef9734e..91458e7b 100644 --- a/scripts/deployments/06a-Deploy-Hub-With-AzFW-Firewall-Policy.ps1 +++ b/scripts/deployments/06a-Deploy-Hub-With-AzFW-Firewall-Policy.ps1 @@ -1,3 +1,5 @@ +#Requires -Modules powershell-yaml + . ".\functions\Set-EnvironmentContext.ps1" # Working Directory diff --git a/scripts/deployments/06b-Deploy-Hub-With-AzFW-Firewall.ps1 b/scripts/deployments/06b-Deploy-Hub-With-AzFW-Firewall.ps1 index c7ad04b3..4b4d83aa 100644 --- a/scripts/deployments/06b-Deploy-Hub-With-AzFW-Firewall.ps1 +++ b/scripts/deployments/06b-Deploy-Hub-With-AzFW-Firewall.ps1 @@ -1,3 +1,5 @@ +#Requires -Modules powershell-yaml + . ".\functions\Set-EnvironmentContext.ps1" # Working Directory diff --git a/scripts/deployments/07-Deploy-Subscriptions.ps1 b/scripts/deployments/07-Deploy-Subscriptions.ps1 index 3935a3bf..b6d10b58 100644 --- a/scripts/deployments/07-Deploy-Subscriptions.ps1 +++ b/scripts/deployments/07-Deploy-Subscriptions.ps1 @@ -1,3 +1,5 @@ +#Requires -Modules powershell-yaml + . ".\functions\Set-EnvironmentContext.ps1" # Working Directory diff --git a/scripts/deployments/functions/Set-EnvironmentContext.ps1 b/scripts/deployments/functions/Set-EnvironmentContext.ps1 index 1552b0fa..223ad09f 100644 --- a/scripts/deployments/functions/Set-EnvironmentContext.ps1 +++ b/scripts/deployments/functions/Set-EnvironmentContext.ps1 @@ -1,4 +1,7 @@ +#Requires -Modules powershell-yaml + Import-Module powershell-yaml + function Set-EnvironmentContext { param ( [string] $WorkingDirectory, From 5802687af14a09227caff7e257e528fea4ebe89b Mon Sep 17 00:00:00 2001 From: Senthuran Sivananthan Date: Thu, 28 Apr 2022 17:02:33 -0400 Subject: [PATCH 15/31] Ensure parameters are mandatory --- scripts/deployments/functions/Set-EnvironmentContext.ps1 | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/scripts/deployments/functions/Set-EnvironmentContext.ps1 b/scripts/deployments/functions/Set-EnvironmentContext.ps1 index 223ad09f..2791ddf4 100644 --- a/scripts/deployments/functions/Set-EnvironmentContext.ps1 +++ b/scripts/deployments/functions/Set-EnvironmentContext.ps1 @@ -4,7 +4,10 @@ Import-Module powershell-yaml function Set-EnvironmentContext { param ( + [Parameter(Mandatory = $true)] [string] $WorkingDirectory, + + [Parameter(Mandatory = $true)] [string] $Environment ) @@ -14,7 +17,12 @@ function Set-EnvironmentContext { $global:NetworkingDirectory = "$WorkingDirectory/config/networking/$Environment" + # Load main environment variables file as YAML $global:EnvironmentConfiguration = Get-Content $EnvironmentConfigurationYamlFilePath | ConvertFrom-Yaml + + # Retrieve the management group hierarchy variable as JSON $global:ManagementGroupHierarchy = $EnvironmentConfiguration.variables['var-managementgroup-hierarchy'] | ConvertFrom-Json + + # Identify the top level management group (the first child underneath Tenant Root Group) $global:TopLevelManagementGroupId = $ManagementGroupHierarchy.children[0].id } \ No newline at end of file From dcefcd9ef6f49c9452ea6c379f7013170c1c408c Mon Sep 17 00:00:00 2001 From: Senthuran Sivananthan Date: Thu, 28 Apr 2022 17:02:56 -0400 Subject: [PATCH 16/31] Wrap in function --- .../01-Deploy-ManagementGroups.ps1 | 45 +++++++++++-------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/scripts/deployments/01-Deploy-ManagementGroups.ps1 b/scripts/deployments/01-Deploy-ManagementGroups.ps1 index 88217239..7b6cc5dc 100644 --- a/scripts/deployments/01-Deploy-ManagementGroups.ps1 +++ b/scripts/deployments/01-Deploy-ManagementGroups.ps1 @@ -1,30 +1,39 @@ #Requires -Modules powershell-yaml . ".\functions\Set-EnvironmentContext.ps1" +function DeployManagementGroups { + param ( + [Parameter(Mandatory = $true)] + [String] $Environment, -# Working Directory -$WorkingDirectory = "../.." + [Parameter(Mandatory = $true)] + [String] $WorkingDirectory + ) -# Set Context -Set-EnvironmentContext -Environment "CanadaESLZ-main" -WorkingDirectory $WorkingDirectory + # Set Context + Set-EnvironmentContext -Environment $Environment -WorkingDirectory $WorkingDirectory -# Deployment -function ProcessManagementGroupHierarchy { - param ( - $parentNode - ) + # Deployment + function ProcessManagementGroupHierarchy { + param ( + [Parameter(Mandatory = $true)] + $parentNode + ) - foreach ($childNode in $parentNode.children) { - $parentManagementGroupId = $parentNode.id - $childManagementGroupId = $childNode.id - $childManagementGroupName = $childNode.name - - Write-Output "Creating $childManagementGroupName [$childManagementGroupId] under $parentManagementGroupId" + foreach ($childNode in $parentNode.children) { + $parentManagementGroupId = $parentNode.id + $childManagementGroupId = $childNode.id + $childManagementGroupName = $childNode.name + + Write-Output "Creating $childManagementGroupName [$childManagementGroupId] under $parentManagementGroupId" - # TODO: Add Azure PS deployment command + # TODO: Add Azure PS deployment command - ProcessManagementGroupHierarchy($childNode) + ProcessManagementGroupHierarchy($childNode) + } } + + ProcessManagementGroupHierarchy($global:ManagementGroupHierarchy) } -ProcessManagementGroupHierarchy($global:ManagementGroupHierarchy) \ No newline at end of file +DeployManagementGroups -WorkingDirectory "../../" -Environment "CanadaESLZ-main" \ No newline at end of file From 16b851eaa92cd4af88096637d85ab0916e4e0a95 Mon Sep 17 00:00:00 2001 From: Senthuran Sivananthan Date: Thu, 28 Apr 2022 17:03:48 -0400 Subject: [PATCH 17/31] Spacing --- scripts/deployments/01-Deploy-ManagementGroups.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/deployments/01-Deploy-ManagementGroups.ps1 b/scripts/deployments/01-Deploy-ManagementGroups.ps1 index 7b6cc5dc..58c1f09c 100644 --- a/scripts/deployments/01-Deploy-ManagementGroups.ps1 +++ b/scripts/deployments/01-Deploy-ManagementGroups.ps1 @@ -1,6 +1,7 @@ #Requires -Modules powershell-yaml . ".\functions\Set-EnvironmentContext.ps1" + function DeployManagementGroups { param ( [Parameter(Mandatory = $true)] From c5db8142c6cd09a9db5453342fe3d4964d868dc5 Mon Sep 17 00:00:00 2001 From: Senthuran Sivananthan Date: Thu, 28 Apr 2022 17:07:37 -0400 Subject: [PATCH 18/31] Wrap in function --- scripts/deployments/02-Deploy-Roles.ps1 | 33 ++++++++++++++++--------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/scripts/deployments/02-Deploy-Roles.ps1 b/scripts/deployments/02-Deploy-Roles.ps1 index d6eb1487..26c166cf 100644 --- a/scripts/deployments/02-Deploy-Roles.ps1 +++ b/scripts/deployments/02-Deploy-Roles.ps1 @@ -2,19 +2,30 @@ . ".\functions\Set-EnvironmentContext.ps1" -# Working Directory -$WorkingDirectory = "../.." -$RolesDirectory = "$WorkingDirectory/roles" +function DeployRoles { + param ( + [Parameter(Mandatory = $true)] + [String] $Environment, -# Set Context -Set-EnvironmentContext -Environment "CanadaESLZ-main" -WorkingDirectory $WorkingDirectory + [Parameter(Mandatory = $true)] + [String] $WorkingDirectory + ) -# Deployment -Write-Output "Using top level management group: $global:TopLevelManagementGroupId" -Write-Output "Deploying role definitions from $global:RolesDirectory" + # Working Directory + $RolesDirectory = "$WorkingDirectory/roles" -foreach ($roleDefinition in Get-ChildItem -Path $RolesDirectory) { - Write-Output "Deploying $($roleDefinition.name)" + # Set Context + Set-EnvironmentContext -Environment $Environment -WorkingDirectory $WorkingDirectory - # TODO: Add Azure PS deployment command + # Deployment + Write-Output "Using top level management group: $global:TopLevelManagementGroupId" + Write-Output "Deploying role definitions from $global:RolesDirectory" + + foreach ($roleDefinition in Get-ChildItem -Path $RolesDirectory) { + Write-Output "Deploying $($roleDefinition.name)" + + # TODO: Add Azure PS deployment command + } } + +DeployRoles -WorkingDirectory "../../" -Environment "CanadaESLZ-main" \ No newline at end of file From 0a671892a5ddd5a258f958d5a09824cf647cb2fa Mon Sep 17 00:00:00 2001 From: Senthuran Sivananthan Date: Thu, 28 Apr 2022 18:39:09 -0400 Subject: [PATCH 19/31] Refactor as functions --- .../01-Deploy-ManagementGroups.ps1 | 40 ----- scripts/deployments/02-Deploy-Roles.ps1 | 31 ---- scripts/deployments/03-Deploy-Logging.ps1 | 21 --- scripts/deployments/04-Deploy-Policy.ps1 | 170 ------------------ .../deployments/05-Deploy-Hub-With-NVA.ps1 | 33 ---- ...a-Deploy-Hub-With-AzFW-Firewall-Policy.ps1 | 17 -- .../06b-Deploy-Hub-With-AzFW-Firewall.ps1 | 37 ---- .../deployments/07-Deploy-Subscriptions.ps1 | 23 --- scripts/deployments/E2E.ps1 | 126 +++++++++++++ .../Functions/HubNetworkWithAzureFirewall.ps1 | 51 ++++++ .../Functions/HubNetworkWithNVA.ps1 | 30 ++++ scripts/deployments/Functions/Logging.ps1 | 21 +++ .../Functions/ManagementGroups.ps1 | 26 +++ scripts/deployments/Functions/Policy.ps1 | 92 ++++++++++ scripts/deployments/Functions/Roles.ps1 | 19 ++ .../SetEnvironmentContext.ps1} | 0 .../deployments/Functions/Subscriptions.ps1 | 26 +++ ...quisites.ps1 => Install-Prerequisites.ps1} | 0 18 files changed, 391 insertions(+), 372 deletions(-) delete mode 100644 scripts/deployments/01-Deploy-ManagementGroups.ps1 delete mode 100644 scripts/deployments/02-Deploy-Roles.ps1 delete mode 100644 scripts/deployments/03-Deploy-Logging.ps1 delete mode 100644 scripts/deployments/04-Deploy-Policy.ps1 delete mode 100644 scripts/deployments/05-Deploy-Hub-With-NVA.ps1 delete mode 100644 scripts/deployments/06a-Deploy-Hub-With-AzFW-Firewall-Policy.ps1 delete mode 100644 scripts/deployments/06b-Deploy-Hub-With-AzFW-Firewall.ps1 delete mode 100644 scripts/deployments/07-Deploy-Subscriptions.ps1 create mode 100644 scripts/deployments/E2E.ps1 create mode 100644 scripts/deployments/Functions/HubNetworkWithAzureFirewall.ps1 create mode 100644 scripts/deployments/Functions/HubNetworkWithNVA.ps1 create mode 100644 scripts/deployments/Functions/Logging.ps1 create mode 100644 scripts/deployments/Functions/ManagementGroups.ps1 create mode 100644 scripts/deployments/Functions/Policy.ps1 create mode 100644 scripts/deployments/Functions/Roles.ps1 rename scripts/deployments/{functions/Set-EnvironmentContext.ps1 => Functions/SetEnvironmentContext.ps1} (100%) create mode 100644 scripts/deployments/Functions/Subscriptions.ps1 rename scripts/deployments/{00-Install-Prerequisites.ps1 => Install-Prerequisites.ps1} (100%) diff --git a/scripts/deployments/01-Deploy-ManagementGroups.ps1 b/scripts/deployments/01-Deploy-ManagementGroups.ps1 deleted file mode 100644 index 58c1f09c..00000000 --- a/scripts/deployments/01-Deploy-ManagementGroups.ps1 +++ /dev/null @@ -1,40 +0,0 @@ -#Requires -Modules powershell-yaml - -. ".\functions\Set-EnvironmentContext.ps1" - -function DeployManagementGroups { - param ( - [Parameter(Mandatory = $true)] - [String] $Environment, - - [Parameter(Mandatory = $true)] - [String] $WorkingDirectory - ) - - # Set Context - Set-EnvironmentContext -Environment $Environment -WorkingDirectory $WorkingDirectory - - # Deployment - function ProcessManagementGroupHierarchy { - param ( - [Parameter(Mandatory = $true)] - $parentNode - ) - - foreach ($childNode in $parentNode.children) { - $parentManagementGroupId = $parentNode.id - $childManagementGroupId = $childNode.id - $childManagementGroupName = $childNode.name - - Write-Output "Creating $childManagementGroupName [$childManagementGroupId] under $parentManagementGroupId" - - # TODO: Add Azure PS deployment command - - ProcessManagementGroupHierarchy($childNode) - } - } - - ProcessManagementGroupHierarchy($global:ManagementGroupHierarchy) -} - -DeployManagementGroups -WorkingDirectory "../../" -Environment "CanadaESLZ-main" \ No newline at end of file diff --git a/scripts/deployments/02-Deploy-Roles.ps1 b/scripts/deployments/02-Deploy-Roles.ps1 deleted file mode 100644 index 26c166cf..00000000 --- a/scripts/deployments/02-Deploy-Roles.ps1 +++ /dev/null @@ -1,31 +0,0 @@ -#Requires -Modules powershell-yaml - -. ".\functions\Set-EnvironmentContext.ps1" - -function DeployRoles { - param ( - [Parameter(Mandatory = $true)] - [String] $Environment, - - [Parameter(Mandatory = $true)] - [String] $WorkingDirectory - ) - - # Working Directory - $RolesDirectory = "$WorkingDirectory/roles" - - # Set Context - Set-EnvironmentContext -Environment $Environment -WorkingDirectory $WorkingDirectory - - # Deployment - Write-Output "Using top level management group: $global:TopLevelManagementGroupId" - Write-Output "Deploying role definitions from $global:RolesDirectory" - - foreach ($roleDefinition in Get-ChildItem -Path $RolesDirectory) { - Write-Output "Deploying $($roleDefinition.name)" - - # TODO: Add Azure PS deployment command - } -} - -DeployRoles -WorkingDirectory "../../" -Environment "CanadaESLZ-main" \ No newline at end of file diff --git a/scripts/deployments/03-Deploy-Logging.ps1 b/scripts/deployments/03-Deploy-Logging.ps1 deleted file mode 100644 index 41fdf550..00000000 --- a/scripts/deployments/03-Deploy-Logging.ps1 +++ /dev/null @@ -1,21 +0,0 @@ -#Requires -Modules powershell-yaml - -. ".\functions\Set-EnvironmentContext.ps1" - -# Working Directory -$WorkingDirectory = "../.." - -# Set Context -Set-EnvironmentContext -Environment "CanadaESLZ-main" -WorkingDirectory $WorkingDirectory - -# Deployment -$DeploymentRegion = $global:EnvironmentConfiguration.variables['var-logging-region'] -$DeploymentManagementGroup = $global:EnvironmentConfiguration.variables['var-logging-managementGroupId'] -$DeploymentSubscription = $global:EnvironmentConfiguration.variables['var-logging-subscriptionId'] -$DeploymentConfigurationFileName = $global:EnvironmentConfiguration.variables['var-logging-configurationFileName'] - -Write-Output "Moving Subscription ($DeploymentSubscription) to Management Group ($DeploymentManagementGroup)" -# TODO: Add Azure PS deployment command - -Write-Output "Deploying $global:LoggingDirectory/$DeploymentConfigurationFileName to $DeploymentSubscription in $DeploymentRegion" -# TODO: Add Azure PS deployment command \ No newline at end of file diff --git a/scripts/deployments/04-Deploy-Policy.ps1 b/scripts/deployments/04-Deploy-Policy.ps1 deleted file mode 100644 index 2e4527b8..00000000 --- a/scripts/deployments/04-Deploy-Policy.ps1 +++ /dev/null @@ -1,170 +0,0 @@ -#Requires -Modules powershell-yaml - -. ".\functions\Set-EnvironmentContext.ps1" - -# Working Directory -$WorkingDirectory = "../.." - -# Set Context -Set-EnvironmentContext -Environment "CanadaESLZ-main" -WorkingDirectory $WorkingDirectory - -$PolicyRootDirectory = "$WorkingDirectory/policy" - -$LoggingSubscription = $global:EnvironmentConfiguration.variables['var-logging-subscriptionId'] -$LoggingConfigurationFileName = $global:EnvironmentConfiguration.variables['var-logging-configurationFileName'] - -#region Policy definition & assignment configuration -$BuiltInPolicySetAssignmentScopes = $( - [PSCustomObject]@{ - ManagementGroupId = $global:TopLevelManagementGroupId - Policies = $( - 'asb', - 'nist80053r4', - 'nist80053r5', - 'pbmm', - 'cis-msft-130', - 'fedramp-moderate', - 'hitrust-hipaa', - 'location' - ) - LoggingSubscriptionId = $LoggingSubscription - LoggingConfigurationFilePath = "$global:LoggingDirectory/$LoggingConfigurationFileName" - } -) - -$CustomPolicySetDefinitions = $( - 'AKS', - 'DefenderForCloud', - 'LogAnalytics', - 'Network', - 'DNSPrivateEndpoints', - 'Tags' -) - -$CustomPolicySetAssignmentScopes = $( - [PSCustomObject]@{ - ManagementGroupId = $global:TopLevelManagementGroupId - Policies = $( - 'AKS', - 'DefenderForCloud', - 'LogAnalytics', - 'Network', - 'Tags' - ) - LoggingSubscriptionId = $LoggingSubscription - LoggingConfigurationFilePath = "$global:LoggingDirectory/$LoggingConfigurationFileName" - } -) -#endregion - -#region Enumerate and deploy built-in policy assignments -$BuiltInPolicySetAssignmentsDirectory = "$PolicyRootDirectory/builtin/assignments" - -foreach ($assignmentScope in $BuiltInPolicySetAssignmentScopes) { - Write-Output "Assignment scope: $($assignmentScope.ManagementGroupId)" - Write-Output "Logging Subscription: $($assignmentScope.LoggingSubscriptionId)" - Write-Output "Logging Configuration: $($assignmentScope.LoggingConfigurationFilePath)" - - foreach ($policy in $assignmentScope.Policies) { - Write-Output "Policy: $policy" - - $DefaultPolicyParameterFilePath = "$BuiltInPolicySetAssignmentsDirectory/$policy.parameters.json" - $AssignmentScopeParameterFilePath = "$BuiltInPolicySetAssignmentsDirectory/$policy-$($assignmentScope.ManagementGroupId).parameters.json" - - # Check if there is an assignment scope specific parameter file. - # The file will have the syntax -.parameters.json - # If not found, then use the default parameter file with syntax .parameters.json - if (Test-Path $AssignmentScopeParameterFilePath -PathType Leaf) { - $PolicyParameterFilePath = $AssignmentScopeParameterFilePath - } else { - $PolicyParameterFilePath = $DefaultPolicyParameterFilePath - } - - Write-Output "Policy: $policy" - Write-Output "- Definition: $BuiltInPolicySetAssignmentsDirectory/$policy.bicep" - Write-Output "- Parameters: $PolicyParameterFilePath" - - # TODO: Add logic to replace templated parameters - - # TODO: Add Azure PS deployment command - - } -} -#endregion - -#region Enumerate and deploy the custom policy definitions -$CustomPolicyDefinitionDirectory = "$PolicyRootDirectory/custom/definitions/policy" - -Get-ChildItem -Directory -Path $CustomPolicyDefinitionDirectory | - Foreach-Object { - $PolicyDefinitionName = $_.Name - $PolicyConfigFilePath = "$($_.FullName)/azurepolicy.config.json" - $PolicyRuleFilePath = "$($_.FullName)/azurepolicy.rules.json" - $PolicyParametersFilePath = "$($_.FullName)/azurepolicy.parameters.json" - - Write-Output "Policy: $PolicyDefinitionName" - Write-Output "- Rule: $PolicyRuleFilePath" - Write-Output "- Parameters: $PolicyParametersFilePath" - Write-Output "- Config: $PolicyConfigFilePath" - - # TODO: Add Azure PS deployment command - } -#endregion - -#region Enumerate and deploy custom policy set definitions -$CustomPolicySetDefinitionsDirectory = "$PolicyRootDirectory/custom/definitions/policyset" - -foreach ($policySetDefinitionName in $CustomPolicySetDefinitions) { - Write-Output "Policy set definition: $policySetDefinitionName" - - $PolicySetDefinitionFilePath = "$($CustomPolicySetDefinitionsDirectory)/$($policySetDefinitionName).bicep" - $PolicySetDefinitionParametersFilePath = "$($CustomPolicySetDefinitionsDirectory)/$($policySetDefinitionName).parameters.json" - - Write-Output "Policy Set: $policySetDefinitionName" - Write-Output "- Definition: $PolicySetDefinitionFilePath" - Write-Output "- Parameters: $PolicySetDefinitionParametersFilePath" - - # TODO: Add logic to load logging configuration - - # TODO: Add logic to replace templated parameters - - # TODO: Add Azure PS deployment command -} -#endregion - -#region Enumerate and deploy custom policy assignments -$CustomPolicySetAssignmentsDirectory = "$PolicyRootDirectory/custom/assignments/policyset" - -foreach ($assignmentScope in $CustomPolicySetAssignmentScopes) { - Write-Output "Assignment scope: $($assignmentScope.ManagementGroupId)" - Write-Output "Logging Subscription: $($assignmentScope.LoggingSubscriptionId)" - Write-Output "Logging Configuration: $($assignmentScope.LoggingConfigurationFilePath)" - - foreach ($policy in $assignmentScope.Policies) { - Write-Output "Policy: $policy" - - $DefaultPolicyParameterFilePath = "$CustomPolicySetAssignmentsDirectory/$policy.parameters.json" - $AssignmentScopeParameterFilePath = "$CustomPolicySetAssignmentsDirectory/$policy-$($assignmentScope.ManagementGroupId).parameters.json" - - # Check if there is an assignment scope specific parameter file. - # The file will have the syntax -.parameters.json - # If not found, then use the default parameter file with syntax .parameters.json - if (Test-Path $AssignmentScopeParameterFilePath -PathType Leaf) { - $PolicyParameterFilePath = $AssignmentScopeParameterFilePath - } else { - $PolicyParameterFilePath = $DefaultPolicyParameterFilePath - } - - Write-Output "Policy: $policy" - Write-Output "- Definition: $CustomPolicySetAssignmentsDirectory/$policy.bicep" - Write-Output "- Parameters: $PolicyParameterFilePath" - - # TODO: Add logic to load logging configuration - - # TODO: Add logic to replace templated parameters - - # TODO: Add Azure PS deployment command - - } -} -#endregion \ No newline at end of file diff --git a/scripts/deployments/05-Deploy-Hub-With-NVA.ps1 b/scripts/deployments/05-Deploy-Hub-With-NVA.ps1 deleted file mode 100644 index a52e5a1e..00000000 --- a/scripts/deployments/05-Deploy-Hub-With-NVA.ps1 +++ /dev/null @@ -1,33 +0,0 @@ -#Requires -Modules powershell-yaml - -. ".\functions\Set-EnvironmentContext.ps1" - -# Working Directory -$WorkingDirectory = "../.." - -# Set Context -Set-EnvironmentContext -Environment "CanadaESLZ-main" -WorkingDirectory $WorkingDirectory - -# Deployment -$DeploymentRegion = $global:EnvironmentConfiguration.variables['var-hubnetwork-region'] -$DeploymentManagementGroup = $global:EnvironmentConfiguration.variables['var-hubnetwork-managementGroupId'] -$DeploymentSubscription = $global:EnvironmentConfiguration.variables['var-hubnetwork-subscriptionId'] -$DeploymentConfigurationFileName = $global:EnvironmentConfiguration.variables['var-hubnetwork-nva-configurationFileName'] - -$LoggingSubscription = $global:EnvironmentConfiguration.variables['var-logging-subscriptionId'] -$LoggingConfigurationFileName = $global:EnvironmentConfiguration.variables['var-logging-configurationFileName'] -$LoggingConfigurationFilePath = "$global:LoggingDirectory/$LoggingConfigurationFileName" - -# TODO: Load logging configuration - -# TODO: Load networking configuration and check if Log Analytics Workspace Id is provided. Otherwise set it. - -Write-Output "Moving Subscription ($DeploymentSubscription) to Management Group ($DeploymentManagementGroup)" -# TODO: Add Azure PS deployment command - -Write-Output "Deploying $global:NetworkingDirectory/$DeploymentConfigurationFileName to $DeploymentSubscription in $DeploymentRegion" -# TODO: Add Azure PS deployment command - -# TODO: Check if Private DNS Zones are managed in the Hub. If so, enable Private DNS Zones policy assignment - -# TODO: Check if DDOS Standard is deployed in the Hub. If so, enable DDOS Standard policy assignment \ No newline at end of file diff --git a/scripts/deployments/06a-Deploy-Hub-With-AzFW-Firewall-Policy.ps1 b/scripts/deployments/06a-Deploy-Hub-With-AzFW-Firewall-Policy.ps1 deleted file mode 100644 index 91458e7b..00000000 --- a/scripts/deployments/06a-Deploy-Hub-With-AzFW-Firewall-Policy.ps1 +++ /dev/null @@ -1,17 +0,0 @@ -#Requires -Modules powershell-yaml - -. ".\functions\Set-EnvironmentContext.ps1" - -# Working Directory -$WorkingDirectory = "../.." - -# Set Context -Set-EnvironmentContext -Environment "CanadaESLZ-main" -WorkingDirectory $WorkingDirectory - -# Deployment -$DeploymentRegion = $global:EnvironmentConfiguration.variables['var-hubnetwork-region'] -$DeploymentSubscription = $global:EnvironmentConfiguration.variables['var-hubnetwork-subscriptionId'] -$DeploymentConfigurationFileName = $global:EnvironmentConfiguration.variables['var-hubnetwork-azfwPolicy-configurationFileName'] - -Write-Output "Deploying $global:NetworkingDirectory/$DeploymentConfigurationFileName to $DeploymentSubscription in $DeploymentRegion" -# TODO: Add Azure PS deployment command \ No newline at end of file diff --git a/scripts/deployments/06b-Deploy-Hub-With-AzFW-Firewall.ps1 b/scripts/deployments/06b-Deploy-Hub-With-AzFW-Firewall.ps1 deleted file mode 100644 index 4b4d83aa..00000000 --- a/scripts/deployments/06b-Deploy-Hub-With-AzFW-Firewall.ps1 +++ /dev/null @@ -1,37 +0,0 @@ -#Requires -Modules powershell-yaml - -. ".\functions\Set-EnvironmentContext.ps1" - -# Working Directory -$WorkingDirectory = "../.." - -# Set Context -Set-EnvironmentContext -Environment "CanadaESLZ-main" -WorkingDirectory $WorkingDirectory - -$LoggingSubscription = $global:EnvironmentConfiguration.variables['var-logging-subscriptionId'] -$LoggingConfigurationFileName = $global:EnvironmentConfiguration.variables['var-logging-configurationFileName'] -$LoggingConfigurationFilePath = "$global:LoggingDirectory/$LoggingConfigurationFileName" - -$DeploymentRegion = $global:EnvironmentConfiguration.variables['var-hubnetwork-region'] -$DeploymentManagementGroup = $global:EnvironmentConfiguration.variables['var-hubnetwork-managementGroupId'] -$DeploymentSubscription = $global:EnvironmentConfiguration.variables['var-hubnetwork-subscriptionId'] -$DeploymentConfigurationFileName = $global:EnvironmentConfiguration.variables['var-hubnetwork-azfw-configurationFileName'] -$FirewallPolicyConfigurationFileName = $global:EnvironmentConfiguration.variables['var-hubnetwork-azfwPolicy-configurationFileName'] - -# Deployment - -# TODO: Load logging configuration - -# TODO: Load networking configuration and check if Log Analytics Workspace Id is provided. Otherwise set it. - -# TODO: Load networking configuration and check if Firewall Policy is provided. Otherwise set it. - -Write-Output "Moving Subscription ($DeploymentSubscription) to Management Group ($DeploymentManagementGroup)" -# TODO: Add Azure PS deployment command - -Write-Output "Deploying $global:NetworkingDirectory/$DeploymentConfigurationFileName to $DeploymentSubscription in $DeploymentRegion" -# TODO: Add Azure PS deployment command - -# TODO: Check if Private DNS Zones are managed in the Hub. If so, enable Private DNS Zones policy assignment - -# TODO: Check if DDOS Standard is deployed in the Hub. If so, enable DDOS Standard policy assignment \ No newline at end of file diff --git a/scripts/deployments/07-Deploy-Subscriptions.ps1 b/scripts/deployments/07-Deploy-Subscriptions.ps1 deleted file mode 100644 index b6d10b58..00000000 --- a/scripts/deployments/07-Deploy-Subscriptions.ps1 +++ /dev/null @@ -1,23 +0,0 @@ -#Requires -Modules powershell-yaml - -. ".\functions\Set-EnvironmentContext.ps1" - -# Working Directory -$WorkingDirectory = "../.." - -# Set Context -Set-EnvironmentContext -Environment "CanadaESLZ-main" -WorkingDirectory $WorkingDirectory - -$Subscriptions = $() - -foreach ($subscription in $subscriptions) { - # TODO: Find the ARM JSON parameters - - # TODO: Ensure there's only 1 parameters file for each subscription - - # TODO: Parse the file name to determine archetype, region and subscription id - - # TODO: Load networking configuration and check if Log Analytics Workspace Id is provided. Otherwise set it. - - # TODO: Add Azure PS deployment command -} \ No newline at end of file diff --git a/scripts/deployments/E2E.ps1 b/scripts/deployments/E2E.ps1 new file mode 100644 index 00000000..de656aa7 --- /dev/null +++ b/scripts/deployments/E2E.ps1 @@ -0,0 +1,126 @@ +#Requires -Modules powershell-yaml + +. ".\functions\SetEnvironmentContext.ps1" +. ".\functions\ManagementGroups.ps1" +. ".\functions\Roles.ps1" +. ".\functions\Logging.ps1" +. ".\functions\Policy.ps1" +. ".\functions\HubNetworkWithNVA.ps1" +. ".\functions\HubNetworkWithAzureFirewall.ps1" +. ".\functions\Subscriptions.ps1" + +$Environment = "CanadaESLZ-main" +$WorkingDirectory = "../.." + +$RolesDirectory = "$WorkingDirectory/roles" +$PolicyDirectory = "$WorkingDirectory/policy" + +# Az Login +# TODO: Login + +# Set Context +Set-EnvironmentContext -Environment $Environment -WorkingDirectory $WorkingDirectory + +# Deploy Management Groups +Deploy-ManagementGroups ` + -ManagementGroupHierarchy $global:ManagementGroupHierarchy + +# Deploy Roles +Deploy-Roles ` + -RolesDirectory $RolesDirectory ` + -ManagementGroupId $global:TopLevelManagementGroupId + +# Deploy Logging +Deploy-Logging ` + -Region $global:EnvironmentConfiguration.variables['var-logging-region'] ` + -ManagementGroupId $global:EnvironmentConfiguration.variables['var-logging-managementGroupId'] ` + -SubscriptionId $global:EnvironmentConfiguration.variables['var-logging-subscriptionId'] ` + -ConfigurationFilePath "$global:LoggingDirectory/$($global:EnvironmentConfiguration.variables['var-logging-configurationFileName'])" + +# Deploy Policies +$LoggingSubscription = $global:EnvironmentConfiguration.variables['var-logging-subscriptionId'] +$LoggingConfigurationFileName = "$global:LoggingDirectory/$global:EnvironmentConfiguration.variables['var-logging-configurationFileName']" + +#Custom Policy Definitions +Deploy-Policy-Definitions ` + -PolicyDefinitionsDirectory "$PolicyDirectory/custom/definitions/policy" ` + -ManagementGroupId $global:TopLevelManagementGroupId + +#Custom Policy Set Definitions +Deploy-PolicySet-Defintions ` + -PolicySetDefinitionsDirectory "$PolicyDirectory/custom/definitions/policyset" ` + -ManagementGroupId $global:TopLevelManagementGroupId ` + -PolicySetDefinitionNames $('AKS', 'DefenderForCloud', 'LogAnalytics', 'Network', 'DNSPrivateEndpoints', 'Tags') + +#Built In Policy Set Assignments +$BuiltInPolicySetAssignmentScopes = $( + [PSCustomObject]@{ + ManagementGroupId = $global:TopLevelManagementGroupId + Policies = $( + 'asb', + 'nist80053r4', + 'nist80053r5', + 'pbmm', + 'cis-msft-130', + 'fedramp-moderate', + 'hitrust-hipaa', + 'location' + ) + LogAnalyticsWorkspaceResourceId = "TODO: SET Dynamically" + LogAnalyticsWorkspaceId = "TODO: SET Dynamically" + LogAnalyticsWorkspaceRetentionInDays = "TODO: SET Dynamically" + } +) + +Deploy-PolicySet-Assignments ` + -PolicySetAssignmentsDirectory "$PolicyDirectory/builtin/assignments" ` + -AssignmentScopes $BuiltInPolicySetAssignmentScopes + +#Custom Policy Sets Assignments +$CustomPolicySetAssignmentScopes = $( + [PSCustomObject]@{ + ManagementGroupId = $global:TopLevelManagementGroupId + Policies = $( + 'AKS', + 'DefenderForCloud', + 'LogAnalytics', + 'Network', + 'Tags' + ) + LogAnalyticsWorkspaceId = "TODO: SET Dynamically" + LogAnalyticsWorkspaceRetentionInDays = "TODO: SET Dynamically" + } +) + +Deploy-PolicySet-Assignments ` + -PolicySetAssignmentsDirectory "$PolicyDirectory/custom/assignments/policyset" ` + -AssignmentScopes $CustomPolicySetAssignmentScopes + +# Hub Networking with NVA +Deploy-HubNetwork-With-NVA ` + -Region $global:EnvironmentConfiguration.variables['var-hubnetwork-region'] ` + -ManagementGroupId $global:EnvironmentConfiguration.variables['var-hubnetwork-managementGroupId'] ` + -SubscriptionId $global:EnvironmentConfiguration.variables['var-hubnetwork-subscriptionId'] ` + -ConfigurationFilePath "$global:NetworkingDirectory/$($global:EnvironmentConfiguration.variables['var-hubnetwork-nva-configurationFileName'])" ` + -LogAnalyticsWorkspaceResourceId "TODO: SET Dynamically" + + +# Hub Networking with Azure Firewall +Deploy-AzureFirewall-Policy ` + -Region $global:EnvironmentConfiguration.variables['var-hubnetwork-region'] ` + -SubscriptionId $global:EnvironmentConfiguration.variables['var-hubnetwork-subscriptionId'] ` + -ConfigurationFilePath "$global:NetworkingDirectory/$($global:EnvironmentConfiguration.variables['var-hubnetwork-azfwPolicy-configurationFileName'])" + +Deploy-HubNetwork-With-AzureFirewall ` + -Region $global:EnvironmentConfiguration.variables['var-hubnetwork-region'] ` + -ManagementGroupId $global:EnvironmentConfiguration.variables['var-hubnetwork-managementGroupId'] ` + -SubscriptionId $global:EnvironmentConfiguration.variables['var-hubnetwork-subscriptionId'] ` + -ConfigurationFilePath "$global:NetworkingDirectory/$($global:EnvironmentConfiguration.variables['var-hubnetwork-azfw-configurationFileName'])" ` + -AzureFirewallPolicyResourceId "TODO: SET Dynamically" ` + -LogAnalyticsWorkspaceResourceId "TODO: SET Dynamically" + +# Subscriptions +Deploy-Subscriptions ` + -Region "canadacentral" ` + -SubscriptionIds $("4f9", "ec6") ` + -LogAnalyticsWorkspaceResourceId "TODO: SET Dynamically" diff --git a/scripts/deployments/Functions/HubNetworkWithAzureFirewall.ps1 b/scripts/deployments/Functions/HubNetworkWithAzureFirewall.ps1 new file mode 100644 index 00000000..ca57f47a --- /dev/null +++ b/scripts/deployments/Functions/HubNetworkWithAzureFirewall.ps1 @@ -0,0 +1,51 @@ +function Deploy-AzureFirewall-Policy { + param ( + [Parameter(Mandatory = $true)] + [String]$Region, + + [Parameter(Mandatory = $true)] + [String]$SubscriptionId, + + [Parameter(Mandatory = $true)] + [String]$ConfigurationFilePath + ) + + # TODO: Add Azure PS deployment command + Write-Output "Deploying $ConfigurationFilePath to $SubscriptionId in $Region" +} + +function Deploy-HubNetwork-With-AzureFirewall { + param ( + [Parameter(Mandatory = $true)] + [String]$Region, + + [Parameter(Mandatory = $true)] + [String]$ManagementGroupId, + + [Parameter(Mandatory = $true)] + [String]$SubscriptionId, + + [Parameter(Mandatory = $true)] + [String]$ConfigurationFilePath, + + [Parameter(Mandatory = $true)] + [String]$AzureFirewallPolicyResourceId, + + [Parameter(Mandatory = $true)] + [String]$LogAnalyticsWorkspaceResourceId + ) + + # TODO: Load networking configuration and check if Log Analytics Workspace Id is provided. Otherwise set it. + + # TODO: Load networking configuration and check if Firewall Policy is provided. Otherwise set it. + + # TODO: Add Azure PS deployment command + Write-Output "Moving Subscription ($SubscriptionId) to Management Group ($ManagementGroupId)" + + # TODO: Add Azure PS deployment command + Write-Output "Deploying $ConfigurationFilePath to $SubscriptionId in $Region" + + # TODO: Check if Private DNS Zones are managed in the Hub. If so, enable Private DNS Zones policy assignment + + # TODO: Check if DDOS Standard is deployed in the Hub. If so, enable DDOS Standard policy assignment +} \ No newline at end of file diff --git a/scripts/deployments/Functions/HubNetworkWithNVA.ps1 b/scripts/deployments/Functions/HubNetworkWithNVA.ps1 new file mode 100644 index 00000000..6901e4be --- /dev/null +++ b/scripts/deployments/Functions/HubNetworkWithNVA.ps1 @@ -0,0 +1,30 @@ +function Deploy-HubNetwork-With-NVA { + param ( + [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 + ) + + # TODO: Load networking configuration and check if Log Analytics Workspace Id is provided. Otherwise set it. + + # TODO: Add Azure PS deployment command + Write-Output "Moving Subscription ($SubscriptionId) to Management Group ($ManagementGroupId)" + + # TODO: Add Azure PS deployment command + Write-Output "Deploying $ConfigurationFilePath to $SubscriptionId in $Region" + + # TODO: Check if Private DNS Zones are managed in the Hub. If so, enable Private DNS Zones policy assignment + + # TODO: Check if DDOS Standard is deployed in the Hub. If so, enable DDOS Standard policy assignment +} \ No newline at end of file diff --git a/scripts/deployments/Functions/Logging.ps1 b/scripts/deployments/Functions/Logging.ps1 new file mode 100644 index 00000000..832fb164 --- /dev/null +++ b/scripts/deployments/Functions/Logging.ps1 @@ -0,0 +1,21 @@ +function Deploy-Logging { + param ( + [Parameter(Mandatory = $true)] + [String]$Region, + + [Parameter(Mandatory = $true)] + [String]$ManagementGroupId, + + [Parameter(Mandatory = $true)] + [String]$SubscriptionId, + + [Parameter(Mandatory = $true)] + [String]$ConfigurationFilePath + ) + + # TODO: Add Azure PS deployment command + Write-Output "Moving Subscription ($SubscriptionId) to Management Group ($ManagementGroupId)" + + # TODO: Add Azure PS deployment command + Write-Output "Deploying $ConfigurationFilePath to $SubscriptionId in $Region" +} \ No newline at end of file diff --git a/scripts/deployments/Functions/ManagementGroups.ps1 b/scripts/deployments/Functions/ManagementGroups.ps1 new file mode 100644 index 00000000..2aeb2bc0 --- /dev/null +++ b/scripts/deployments/Functions/ManagementGroups.ps1 @@ -0,0 +1,26 @@ +function Deploy-ManagementGroups { + param ( + [Parameter(Mandatory = $true)] + $ManagementGroupHierarchy + ) + function Process-ManagementGroup-Hierarchy { + param ( + [Parameter(Mandatory = $true)] + $ParentNode + ) + + foreach ($childNode in $ParentNode.children) { + $parentManagementGroupId = $ParentNode.id + $childManagementGroupId = $childNode.id + $childManagementGroupName = $childNode.name + + Write-Output "Creating $childManagementGroupName [$childManagementGroupId] under $parentManagementGroupId" + + # TODO: Add Azure PS deployment command + + Process-ManagementGroup-Hierarchy($childNode) + } + } + + Process-ManagementGroup-Hierarchy($ManagementGroupHierarchy) +} \ No newline at end of file diff --git a/scripts/deployments/Functions/Policy.ps1 b/scripts/deployments/Functions/Policy.ps1 new file mode 100644 index 00000000..ff15adbb --- /dev/null +++ b/scripts/deployments/Functions/Policy.ps1 @@ -0,0 +1,92 @@ +function Deploy-Policy-Definitions { + param( + [Parameter(Mandatory = $true)] + [String] $PolicyDefinitionsDirectory, + + [Parameter(Mandatory = $true)] + [PSCustomObject] $ManagementGroupId + ) + Get-ChildItem -Directory -Path $PolicyDefinitionsDirectory | + Foreach-Object { + $PolicyDefinitionName = $_.Name + $PolicyConfigFilePath = "$($_.FullName)/azurepolicy.config.json" + $PolicyRuleFilePath = "$($_.FullName)/azurepolicy.rules.json" + $PolicyParametersFilePath = "$($_.FullName)/azurepolicy.parameters.json" + + Write-Output "Policy: $PolicyDefinitionName" + Write-Output "- Rule: $PolicyRuleFilePath" + Write-Output "- Parameters: $PolicyParametersFilePath" + Write-Output "- Config: $PolicyConfigFilePath" + + # TODO: Add Azure PS deployment command + } +} + +function Deploy-PolicySet-Defintions { + param( + [Parameter(Mandatory = $true)] + [String] $PolicySetDefinitionsDirectory, + + [Parameter(Mandatory = $true)] + [String[]] $PolicySetDefinitionNames, + + [Parameter(Mandatory = $true)] + [PSCustomObject] $ManagementGroupId + ) + + foreach ($policySetDefinitionName in $PolicySetDefinitionNames) { + Write-Output "Policy set definition: $policySetDefinitionName" + + $PolicySetDefinitionFilePath = "$($PolicySetDefinitionsDirectory)/$($policySetDefinitionName).bicep" + $PolicySetDefinitionParametersFilePath = "$($PolicySetDefinitionsDirectory)/$($policySetDefinitionName).parameters.json" + + Write-Output "Policy Set: $policySetDefinitionName" + Write-Output "- Definition: $PolicySetDefinitionFilePath" + Write-Output "- Parameters: $PolicySetDefinitionParametersFilePath" + + # TODO: Add logic to load logging configuration + + # TODO: Add logic to replace templated parameters + + # TODO: Add Azure PS deployment command + } +} + +function Deploy-PolicySet-Assignments { + param( + [Parameter(Mandatory = $true)] + [String] $PolicySetAssignmentsDirectory, + + [Parameter(Mandatory = $true)] + [PSCustomObject] $AssignmentScopes + ) + + foreach ($assignmentScope in $AssignmentScopes) { + Write-Output "Assignment scope: $($assignmentScope.ManagementGroupId)" + + foreach ($policy in $assignmentScope.Policies) { + Write-Output "Policy: $policy" + + $DefaultPolicyParameterFilePath = "$PolicySetAssignmentsDirectory/$policy.parameters.json" + $AssignmentScopeParameterFilePath = "$PolicySetAssignmentsDirectory/$policy-$($assignmentScope.ManagementGroupId).parameters.json" + + # Check if there is an assignment scope specific parameter file. + # The file will have the syntax -.parameters.json + # If not found, then use the default parameter file with syntax .parameters.json + if (Test-Path $AssignmentScopeParameterFilePath -PathType Leaf) { + $PolicyParameterFilePath = $AssignmentScopeParameterFilePath + } else { + $PolicyParameterFilePath = $DefaultPolicyParameterFilePath + } + + Write-Output "Policy: $policy" + Write-Output "- Definition: $PolicySetAssignmentsDirectory/$policy.bicep" + Write-Output "- Parameters: $PolicyParameterFilePath" + + # TODO: Add logic to replace templated parameters + + # TODO: Add Azure PS deployment command + + } + } +} diff --git a/scripts/deployments/Functions/Roles.ps1 b/scripts/deployments/Functions/Roles.ps1 new file mode 100644 index 00000000..0d13d4ed --- /dev/null +++ b/scripts/deployments/Functions/Roles.ps1 @@ -0,0 +1,19 @@ +function Deploy-Roles { + param ( + [Parameter(Mandatory = $true)] + [String] $RolesDirectory, + + [Parameter(Mandatory = $true)] + [String] $ManagementGroupId + ) + + # Deployment + Write-Output "Deploying roles to management group: $ManagementGroupId" + Write-Output "Deploying role definitions from $RolesDirectory" + + foreach ($roleDefinition in Get-ChildItem -Path $RolesDirectory) { + Write-Output "Deploying $($roleDefinition.name)" + + # TODO: Add Azure PS deployment command + } +} \ No newline at end of file diff --git a/scripts/deployments/functions/Set-EnvironmentContext.ps1 b/scripts/deployments/Functions/SetEnvironmentContext.ps1 similarity index 100% rename from scripts/deployments/functions/Set-EnvironmentContext.ps1 rename to scripts/deployments/Functions/SetEnvironmentContext.ps1 diff --git a/scripts/deployments/Functions/Subscriptions.ps1 b/scripts/deployments/Functions/Subscriptions.ps1 new file mode 100644 index 00000000..f9332e6d --- /dev/null +++ b/scripts/deployments/Functions/Subscriptions.ps1 @@ -0,0 +1,26 @@ +function Deploy-Subscriptions { + param ( + [Parameter(Mandatory = $true)] + [String]$Region, + + [Parameter(Mandatory = $true)] + [String[]] $SubscriptionIds, + + [Parameter(Mandatory = $true)] + [String] $LogAnalyticsWorkspaceResourceId + ) + + foreach ($subscriptionId in $SubscriptionIds) { + Write-Output "Deploying Subscription: $subscriptionId" + + # TODO: Find the ARM JSON parameters + + # TODO: Ensure there's only 1 parameters file for each subscription + + # TODO: Parse the file name to determine archetype, region and subscription id + + # TODO: Load networking configuration and check if Log Analytics Workspace Id is provided. Otherwise set it. + + # TODO: Add Azure PS deployment command + } +} \ No newline at end of file diff --git a/scripts/deployments/00-Install-Prerequisites.ps1 b/scripts/deployments/Install-Prerequisites.ps1 similarity index 100% rename from scripts/deployments/00-Install-Prerequisites.ps1 rename to scripts/deployments/Install-Prerequisites.ps1 From 5dc0b152fe463d2122f7f333b5b5ba5fab90123e Mon Sep 17 00:00:00 2001 From: Senthuran Sivananthan Date: Fri, 29 Apr 2022 10:15:33 -0400 Subject: [PATCH 20/31] Refactor --- scripts/deployments/E2E.ps1 | 176 ++++++++---------- .../Functions/EnvironmentContext.ps1 | 45 +++++ .../Functions/HubNetworkWithAzureFirewall.ps1 | 22 ++- .../Functions/HubNetworkWithNVA.ps1 | 2 +- scripts/deployments/Functions/Logging.ps1 | 24 ++- .../Functions/ManagementGroups.ps1 | 8 +- scripts/deployments/Functions/Policy.ps1 | 58 +++--- scripts/deployments/Functions/Roles.ps1 | 2 +- .../Functions/SetEnvironmentContext.ps1 | 28 --- .../deployments/Functions/Subscriptions.ps1 | 2 +- 10 files changed, 205 insertions(+), 162 deletions(-) create mode 100644 scripts/deployments/Functions/EnvironmentContext.ps1 delete mode 100644 scripts/deployments/Functions/SetEnvironmentContext.ps1 diff --git a/scripts/deployments/E2E.ps1 b/scripts/deployments/E2E.ps1 index de656aa7..2195d33d 100644 --- a/scripts/deployments/E2E.ps1 +++ b/scripts/deployments/E2E.ps1 @@ -1,126 +1,104 @@ #Requires -Modules powershell-yaml -. ".\functions\SetEnvironmentContext.ps1" -. ".\functions\ManagementGroups.ps1" -. ".\functions\Roles.ps1" -. ".\functions\Logging.ps1" -. ".\functions\Policy.ps1" -. ".\functions\HubNetworkWithNVA.ps1" -. ".\functions\HubNetworkWithAzureFirewall.ps1" -. ".\functions\Subscriptions.ps1" - -$Environment = "CanadaESLZ-main" +. ".\Functions\EnvironmentContext.ps1" +. ".\Functions\ManagementGroups.ps1" +. ".\Functions\Roles.ps1" +. ".\Functions\Logging.ps1" +. ".\Functions\Policy.ps1" +. ".\Functions\HubNetworkWithNVA.ps1" +. ".\Functions\HubNetworkWithAzureFirewall.ps1" +. ".\Functions\Subscriptions.ps1" + +$EnvironmentName = "CanadaESLZ-main" $WorkingDirectory = "../.." -$RolesDirectory = "$WorkingDirectory/roles" -$PolicyDirectory = "$WorkingDirectory/policy" - # Az Login # TODO: Login -# Set Context -Set-EnvironmentContext -Environment $Environment -WorkingDirectory $WorkingDirectory +# Set Azure Landing Zones Context +$Context = New-EnvironmentContext -Environment $EnvironmentName -WorkingDirectory $WorkingDirectory # Deploy Management Groups -Deploy-ManagementGroups ` - -ManagementGroupHierarchy $global:ManagementGroupHierarchy +Set-ManagementGroups ` + -ManagementGroupHierarchy $Context.ManagementGroupHierarchy # Deploy Roles -Deploy-Roles ` - -RolesDirectory $RolesDirectory ` - -ManagementGroupId $global:TopLevelManagementGroupId +Set-Roles ` + -RolesDirectory $Context.RolesDirectory ` + -ManagementGroupId $Context.TopLevelManagementGroupId # Deploy Logging -Deploy-Logging ` - -Region $global:EnvironmentConfiguration.variables['var-logging-region'] ` - -ManagementGroupId $global:EnvironmentConfiguration.variables['var-logging-managementGroupId'] ` - -SubscriptionId $global:EnvironmentConfiguration.variables['var-logging-subscriptionId'] ` - -ConfigurationFilePath "$global:LoggingDirectory/$($global:EnvironmentConfiguration.variables['var-logging-configurationFileName'])" +Set-Logging ` + -Region $Context.Variables['var-logging-region'] ` + -ManagementGroupId $Context.Variables['var-logging-managementGroupId'] ` + -SubscriptionId $Context.Variables['var-logging-subscriptionId'] ` + -ConfigurationFilePath "$($Context.LoggingDirectory)/$($Context.Variables['var-logging-configurationFileName'])" + +# Get Logging Configuration using logging configuration file & Azure environment +$LoggingConfiguration = Get-LoggingConfiguration ` + -ConfigurationFilePath "$($Context.LoggingDirectory)/$($Context.Variables['var-logging-configurationFileName'])" ` + -SubscriptionId $Context.Variables['var-logging-subscriptionId'] # Deploy Policies -$LoggingSubscription = $global:EnvironmentConfiguration.variables['var-logging-subscriptionId'] -$LoggingConfigurationFileName = "$global:LoggingDirectory/$global:EnvironmentConfiguration.variables['var-logging-configurationFileName']" - -#Custom Policy Definitions -Deploy-Policy-Definitions ` - -PolicyDefinitionsDirectory "$PolicyDirectory/custom/definitions/policy" ` - -ManagementGroupId $global:TopLevelManagementGroupId - -#Custom Policy Set Definitions -Deploy-PolicySet-Defintions ` - -PolicySetDefinitionsDirectory "$PolicyDirectory/custom/definitions/policyset" ` - -ManagementGroupId $global:TopLevelManagementGroupId ` + +## Custom Policy Definitions +Set-Policy-Definitions ` + -PolicyDefinitionsDirectory $Context.PolicyCustomDefinitionDirectory ` + -ManagementGroupId $Context.TopLevelManagementGroupId + +## Custom Policy Set Definitions +Set-PolicySet-Defintions ` + -PolicySetDefinitionsDirectory $Context.PolicySetCustomDefinitionDirectory ` + -ManagementGroupId $Context.TopLevelManagementGroupId ` -PolicySetDefinitionNames $('AKS', 'DefenderForCloud', 'LogAnalytics', 'Network', 'DNSPrivateEndpoints', 'Tags') -#Built In Policy Set Assignments -$BuiltInPolicySetAssignmentScopes = $( - [PSCustomObject]@{ - ManagementGroupId = $global:TopLevelManagementGroupId - Policies = $( - 'asb', - 'nist80053r4', - 'nist80053r5', - 'pbmm', - 'cis-msft-130', - 'fedramp-moderate', - 'hitrust-hipaa', - 'location' - ) - LogAnalyticsWorkspaceResourceId = "TODO: SET Dynamically" - LogAnalyticsWorkspaceId = "TODO: SET Dynamically" - LogAnalyticsWorkspaceRetentionInDays = "TODO: SET Dynamically" - } -) - -Deploy-PolicySet-Assignments ` - -PolicySetAssignmentsDirectory "$PolicyDirectory/builtin/assignments" ` - -AssignmentScopes $BuiltInPolicySetAssignmentScopes +## Built In Policy Set Assignments +Set-PolicySet-Assignments ` + -PolicySetAssignmentsDirectory $Context.PolicySetBuiltInAssignmentsDirectory ` + -PolicySetAssignmentManagementGroupId $Context.TopLevelManagementGroupId ` + -PolicySetAssignmentNames $('asb', 'nist80053r4', 'nist80053r5', 'pbmm', 'cis-msft-130', 'fedramp-moderate', 'hitrust-hipaa', 'location') ` + -LogAnalyticsWorkspaceResourceId $LoggingConfiguration.LogAnalyticsWorkspaceResourceId ` + -LogAnalyticsWorkspaceId $LoggingConfiguration.LogAnalyticsWorkspaceId ` + -LogAnalyticsWorkspaceRetentionInDays $LoggingConfiguration.LogRetentionInDays #Custom Policy Sets Assignments -$CustomPolicySetAssignmentScopes = $( - [PSCustomObject]@{ - ManagementGroupId = $global:TopLevelManagementGroupId - Policies = $( - 'AKS', - 'DefenderForCloud', - 'LogAnalytics', - 'Network', - 'Tags' - ) - LogAnalyticsWorkspaceId = "TODO: SET Dynamically" - LogAnalyticsWorkspaceRetentionInDays = "TODO: SET Dynamically" - } -) - -Deploy-PolicySet-Assignments ` - -PolicySetAssignmentsDirectory "$PolicyDirectory/custom/assignments/policyset" ` - -AssignmentScopes $CustomPolicySetAssignmentScopes +Set-PolicySet-Assignments ` + -PolicySetAssignmentsDirectory $Context.PolicySetCustomAssignmentsDirectory ` + -PolicySetAssignmentManagementGroupId $Context.TopLevelManagementGroupId ` + -PolicySetAssignmentNames $('AKS', 'DefenderForCloud', 'LogAnalytics', 'Network', 'Tags') ` + -LogAnalyticsWorkspaceResourceId $LoggingConfiguration.LogAnalyticsWorkspaceResourceId ` + -LogAnalyticsWorkspaceId $LoggingConfiguration.LogAnalyticsWorkspaceId ` + -LogAnalyticsWorkspaceRetentionInDays $LoggingConfiguration.LogRetentionInDays # Hub Networking with NVA -Deploy-HubNetwork-With-NVA ` - -Region $global:EnvironmentConfiguration.variables['var-hubnetwork-region'] ` - -ManagementGroupId $global:EnvironmentConfiguration.variables['var-hubnetwork-managementGroupId'] ` - -SubscriptionId $global:EnvironmentConfiguration.variables['var-hubnetwork-subscriptionId'] ` - -ConfigurationFilePath "$global:NetworkingDirectory/$($global:EnvironmentConfiguration.variables['var-hubnetwork-nva-configurationFileName'])" ` - -LogAnalyticsWorkspaceResourceId "TODO: SET Dynamically" - +Set-HubNetwork-With-NVA ` + -Region $Context.Variables['var-hubnetwork-region'] ` + -ManagementGroupId $Context.Variables['var-hubnetwork-managementGroupId'] ` + -SubscriptionId $Context.Variables['var-hubnetwork-subscriptionId'] ` + -ConfigurationFilePath "$($Context.NetworkingDirectory)/$($Context.Variables['var-hubnetwork-nva-configurationFileName'])" ` + -LogAnalyticsWorkspaceResourceId $LoggingConfiguration.LogAnalyticsWorkspaceResourceId # Hub Networking with Azure Firewall -Deploy-AzureFirewall-Policy ` - -Region $global:EnvironmentConfiguration.variables['var-hubnetwork-region'] ` - -SubscriptionId $global:EnvironmentConfiguration.variables['var-hubnetwork-subscriptionId'] ` - -ConfigurationFilePath "$global:NetworkingDirectory/$($global:EnvironmentConfiguration.variables['var-hubnetwork-azfwPolicy-configurationFileName'])" - -Deploy-HubNetwork-With-AzureFirewall ` - -Region $global:EnvironmentConfiguration.variables['var-hubnetwork-region'] ` - -ManagementGroupId $global:EnvironmentConfiguration.variables['var-hubnetwork-managementGroupId'] ` - -SubscriptionId $global:EnvironmentConfiguration.variables['var-hubnetwork-subscriptionId'] ` - -ConfigurationFilePath "$global:NetworkingDirectory/$($global:EnvironmentConfiguration.variables['var-hubnetwork-azfw-configurationFileName'])" ` - -AzureFirewallPolicyResourceId "TODO: SET Dynamically" ` - -LogAnalyticsWorkspaceResourceId "TODO: SET Dynamically" +Set-AzureFirewallPolicy ` + -Region $Context.Variables['var-hubnetwork-region'] ` + -SubscriptionId $Context.Variables['var-hubnetwork-subscriptionId'] ` + -ConfigurationFilePath "$($Context.NetworkingDirectory)/$($Context.Variables['var-hubnetwork-azfwPolicy-configurationFileName'])" + +# Retrieve Azure Firewall Configuration +$AzureFirewallConfiguration = Get-AzureFirewallPolicy ` + -SubscriptionId $Context.Variables['var-hubnetwork-subscriptionId'] ` + -ConfigurationFilePath "$($Context.NetworkingDirectory)/$($Context.Variables['var-hubnetwork-azfwPolicy-configurationFileName'])" + +Set-HubNetwork-With-AzureFirewall ` + -Region $Context.Variables['var-hubnetwork-region'] ` + -ManagementGroupId $Context.Variables['var-hubnetwork-managementGroupId'] ` + -SubscriptionId $Context.Variables['var-hubnetwork-subscriptionId'] ` + -ConfigurationFilePath "$($Context.NetworkingDirectory)/$($Context.Variables['var-hubnetwork-azfw-configurationFileName'])" ` + -AzureFirewallPolicyResourceId $AzureFirewallConfiguration.AzureFirewallPolicyResourceId ` + -LogAnalyticsWorkspaceResourceId $LoggingConfiguration.LogAnalyticsWorkspaceResourceId # Subscriptions -Deploy-Subscriptions ` +Set-Subscriptions ` -Region "canadacentral" ` -SubscriptionIds $("4f9", "ec6") ` - -LogAnalyticsWorkspaceResourceId "TODO: SET Dynamically" + -LogAnalyticsWorkspaceResourceId $LoggingConfiguration.LogAnalyticsWorkspaceResourceId \ No newline at end of file diff --git a/scripts/deployments/Functions/EnvironmentContext.ps1 b/scripts/deployments/Functions/EnvironmentContext.ps1 new file mode 100644 index 00000000..ffd4cc85 --- /dev/null +++ b/scripts/deployments/Functions/EnvironmentContext.ps1 @@ -0,0 +1,45 @@ +#Requires -Modules powershell-yaml + +Import-Module powershell-yaml + +function New-EnvironmentContext { + param ( + [Parameter(Mandatory = $true)] + [string] $WorkingDirectory, + + [Parameter(Mandatory = $true)] + [string] $Environment + ) + + $EnvironmentConfigurationYamlFilePath = "$WorkingDirectory/config/variables/$Environment.yml" + + # Load main environment variables file as YAML + $EnvironmentConfiguration = Get-Content $EnvironmentConfigurationYamlFilePath | ConvertFrom-Yaml + $Variables = $EnvironmentConfiguration.variables + + # Retrieve the management group hierarchy variable as JSON + $ManagementGroupHierarchy = $Variables['var-managementgroup-hierarchy'] | ConvertFrom-Json + + $PolicyDirectory = "$WorkingDirectory/policy" + + # Create a new context object + return [PSCustomObject]@{ + EnvironmentConfigurationYamlFilePath = $EnvironmentConfigurationYamlFilePath + + RolesDirectory = "$WorkingDirectory/roles" + + PolicyCustomDefinitionDirectory = "$PolicyDirectory/custom/definitions/policy" + PolicySetCustomDefinitionDirectory = "$PolicyDirectory/custom/definitions/policyset" + PolicySetCustomAssignmentsDirectory = "$PolicyDirectory/custom/assignments/policyset" + PolicySetBuiltInAssignmentsDirectory = "$PolicyDirectory/builtin/assignments" + + LoggingDirectory = "$WorkingDirectory/config/logging/$Environment" + NetworkingDirectory = "$WorkingDirectory/config/networking/$Environment" + + Variables = $Variables + ManagementGroupHierarchy = $ManagementGroupHierarchy + + # Identify the top level management group (the first child underneath Tenant Root Group) + TopLevelManagementGroupId = $ManagementGroupHierarchy.children[0].id + } +} \ No newline at end of file diff --git a/scripts/deployments/Functions/HubNetworkWithAzureFirewall.ps1 b/scripts/deployments/Functions/HubNetworkWithAzureFirewall.ps1 index ca57f47a..3833beb4 100644 --- a/scripts/deployments/Functions/HubNetworkWithAzureFirewall.ps1 +++ b/scripts/deployments/Functions/HubNetworkWithAzureFirewall.ps1 @@ -1,4 +1,22 @@ -function Deploy-AzureFirewall-Policy { +function Get-AzureFirewallPolicy { + param ( + [Parameter(Mandatory = $true)] + [String]$ConfigurationFilePath, + + [Parameter(Mandatory = $true)] + [String]$SubscriptionId + ) + + $Configuration = Get-Content $ConfigurationFilePath | ConvertFrom-Json + + # TODO: Retreive Azure Firewall Policy Id + + return [PSCustomObject]@{ + AzureFirewallPolicyResourceId = "TODO" + } +} + +function Set-AzureFirewallPolicy { param ( [Parameter(Mandatory = $true)] [String]$Region, @@ -14,7 +32,7 @@ function Deploy-AzureFirewall-Policy { Write-Output "Deploying $ConfigurationFilePath to $SubscriptionId in $Region" } -function Deploy-HubNetwork-With-AzureFirewall { +function Set-HubNetwork-With-AzureFirewall { param ( [Parameter(Mandatory = $true)] [String]$Region, diff --git a/scripts/deployments/Functions/HubNetworkWithNVA.ps1 b/scripts/deployments/Functions/HubNetworkWithNVA.ps1 index 6901e4be..ac315bbd 100644 --- a/scripts/deployments/Functions/HubNetworkWithNVA.ps1 +++ b/scripts/deployments/Functions/HubNetworkWithNVA.ps1 @@ -1,4 +1,4 @@ -function Deploy-HubNetwork-With-NVA { +function Set-HubNetwork-With-NVA { param ( [Parameter(Mandatory = $true)] [String]$Region, diff --git a/scripts/deployments/Functions/Logging.ps1 b/scripts/deployments/Functions/Logging.ps1 index 832fb164..fce4c713 100644 --- a/scripts/deployments/Functions/Logging.ps1 +++ b/scripts/deployments/Functions/Logging.ps1 @@ -1,4 +1,26 @@ -function Deploy-Logging { +function Get-LoggingConfiguration { + param ( + [Parameter(Mandatory = $true)] + [String]$ConfigurationFilePath, + + [Parameter(Mandatory = $true)] + [String]$SubscriptionId + ) + + $Configuration = Get-Content $ConfigurationFilePath | ConvertFrom-Json + + # TODO: Retreive Log Analytics Workspace Resource Id & Workspace Id + + return [PSCustomObject]@{ + ResourceGroup = $Configuration.parameters.logAnalyticsResourceGroupName.value + LogAnalyticsWorkspaceName = $Configuration.parameters.logAnalyticsWorkspaceName.value + LogRetentionInDays = $Configuration.parameters.logAnalyticsRetentionInDays.value + LogAnalyticsWorkspaceResourceId = "TODO" + LogAnalyticsWorkspaceId = "TODO" + } +} + +function Set-Logging { param ( [Parameter(Mandatory = $true)] [String]$Region, diff --git a/scripts/deployments/Functions/ManagementGroups.ps1 b/scripts/deployments/Functions/ManagementGroups.ps1 index 2aeb2bc0..3973ba7b 100644 --- a/scripts/deployments/Functions/ManagementGroups.ps1 +++ b/scripts/deployments/Functions/ManagementGroups.ps1 @@ -1,9 +1,9 @@ -function Deploy-ManagementGroups { +function Set-ManagementGroups { param ( [Parameter(Mandatory = $true)] $ManagementGroupHierarchy ) - function Process-ManagementGroup-Hierarchy { + function Set-ChildManagementGroups { param ( [Parameter(Mandatory = $true)] $ParentNode @@ -18,9 +18,9 @@ function Deploy-ManagementGroups { # TODO: Add Azure PS deployment command - Process-ManagementGroup-Hierarchy($childNode) + Set-ChildManagementGroups($childNode) } } - Process-ManagementGroup-Hierarchy($ManagementGroupHierarchy) + Set-ChildManagementGroups($ManagementGroupHierarchy) } \ No newline at end of file diff --git a/scripts/deployments/Functions/Policy.ps1 b/scripts/deployments/Functions/Policy.ps1 index ff15adbb..5999c566 100644 --- a/scripts/deployments/Functions/Policy.ps1 +++ b/scripts/deployments/Functions/Policy.ps1 @@ -1,4 +1,4 @@ -function Deploy-Policy-Definitions { +function Set-Policy-Definitions { param( [Parameter(Mandatory = $true)] [String] $PolicyDefinitionsDirectory, @@ -22,7 +22,7 @@ function Deploy-Policy-Definitions { } } -function Deploy-PolicySet-Defintions { +function Set-PolicySet-Defintions { param( [Parameter(Mandatory = $true)] [String] $PolicySetDefinitionsDirectory, @@ -52,41 +52,49 @@ function Deploy-PolicySet-Defintions { } } -function Deploy-PolicySet-Assignments { +function Set-PolicySet-Assignments { param( [Parameter(Mandatory = $true)] [String] $PolicySetAssignmentsDirectory, [Parameter(Mandatory = $true)] - [PSCustomObject] $AssignmentScopes - ) + [String] $PolicySetAssignmentManagementGroupId, - foreach ($assignmentScope in $AssignmentScopes) { - Write-Output "Assignment scope: $($assignmentScope.ManagementGroupId)" - - foreach ($policy in $assignmentScope.Policies) { - Write-Output "Policy: $policy" + [Parameter(Mandatory = $true)] + [String[]] $PolicySetAssignmentNames, - $DefaultPolicyParameterFilePath = "$PolicySetAssignmentsDirectory/$policy.parameters.json" - $AssignmentScopeParameterFilePath = "$PolicySetAssignmentsDirectory/$policy-$($assignmentScope.ManagementGroupId).parameters.json" + [Parameter(Mandatory = $true)] + [String] $LogAnalyticsWorkspaceResourceId, - # Check if there is an assignment scope specific parameter file. - # The file will have the syntax -.parameters.json - # If not found, then use the default parameter file with syntax .parameters.json - if (Test-Path $AssignmentScopeParameterFilePath -PathType Leaf) { - $PolicyParameterFilePath = $AssignmentScopeParameterFilePath - } else { - $PolicyParameterFilePath = $DefaultPolicyParameterFilePath - } + [Parameter(Mandatory = $true)] + [String] $LogAnalyticsWorkspaceId, - Write-Output "Policy: $policy" - Write-Output "- Definition: $PolicySetAssignmentsDirectory/$policy.bicep" - Write-Output "- Parameters: $PolicyParameterFilePath" + [Parameter(Mandatory = $true)] + [Int32] $LogAnalyticsWorkspaceRetentionInDays + ) - # TODO: Add logic to replace templated parameters + foreach ($policySetAssignmentName in $PolicySetAssignmentNames) { + Write-Output "Policy Set assignment Name: $($policySetAssignmentName)" - # TODO: Add Azure PS deployment command + $DefaultPolicyParameterFilePath = "$PolicySetAssignmentsDirectory/$policySetAssignmentName.parameters.json" + $AssignmentScopeParameterFilePath = "$PolicySetAssignmentsDirectory/$policySetAssignmentName-$PolicySetAssignmentManagementGroupId.parameters.json" + # Check if there is an assignment scope specific parameter file. + # The file will have the syntax -.parameters.json + # If not found, then use the default parameter file with syntax .parameters.json + if (Test-Path $AssignmentScopeParameterFilePath -PathType Leaf) { + $PolicySetParameterFilePath = $AssignmentScopeParameterFilePath + } else { + $PolicySetParameterFilePath = $DefaultPolicyParameterFilePath } + + Write-Output "Policy: $policy" + Write-Output "- Definition: $PolicySetAssignmentsDirectory/$policySetAssignmentName.bicep" + Write-Output "- Parameters: $PolicySetParameterFilePath" + + # TODO: Add logic to replace templated parameters + + # TODO: Add Azure PS deployment command + } } diff --git a/scripts/deployments/Functions/Roles.ps1 b/scripts/deployments/Functions/Roles.ps1 index 0d13d4ed..fb73e1f6 100644 --- a/scripts/deployments/Functions/Roles.ps1 +++ b/scripts/deployments/Functions/Roles.ps1 @@ -1,4 +1,4 @@ -function Deploy-Roles { +function Set-Roles { param ( [Parameter(Mandatory = $true)] [String] $RolesDirectory, diff --git a/scripts/deployments/Functions/SetEnvironmentContext.ps1 b/scripts/deployments/Functions/SetEnvironmentContext.ps1 deleted file mode 100644 index 2791ddf4..00000000 --- a/scripts/deployments/Functions/SetEnvironmentContext.ps1 +++ /dev/null @@ -1,28 +0,0 @@ -#Requires -Modules powershell-yaml - -Import-Module powershell-yaml - -function Set-EnvironmentContext { - param ( - [Parameter(Mandatory = $true)] - [string] $WorkingDirectory, - - [Parameter(Mandatory = $true)] - [string] $Environment - ) - - $global:EnvironmentConfigurationYamlFilePath = "$WorkingDirectory/config/variables/$Environment.yml" - - $global:LoggingDirectory = "$WorkingDirectory/config/logging/$Environment" - $global:NetworkingDirectory = "$WorkingDirectory/config/networking/$Environment" - - - # Load main environment variables file as YAML - $global:EnvironmentConfiguration = Get-Content $EnvironmentConfigurationYamlFilePath | ConvertFrom-Yaml - - # Retrieve the management group hierarchy variable as JSON - $global:ManagementGroupHierarchy = $EnvironmentConfiguration.variables['var-managementgroup-hierarchy'] | ConvertFrom-Json - - # Identify the top level management group (the first child underneath Tenant Root Group) - $global:TopLevelManagementGroupId = $ManagementGroupHierarchy.children[0].id -} \ No newline at end of file diff --git a/scripts/deployments/Functions/Subscriptions.ps1 b/scripts/deployments/Functions/Subscriptions.ps1 index f9332e6d..d3afbd65 100644 --- a/scripts/deployments/Functions/Subscriptions.ps1 +++ b/scripts/deployments/Functions/Subscriptions.ps1 @@ -1,4 +1,4 @@ -function Deploy-Subscriptions { +function Set-Subscriptions { param ( [Parameter(Mandatory = $true)] [String]$Region, From d058b882936d531f0ac6f54c959f7608974c79a9 Mon Sep 17 00:00:00 2001 From: Senthuran Sivananthan Date: Fri, 29 Apr 2022 11:38:01 -0400 Subject: [PATCH 21/31] Create MGs --- scripts/deployments/E2E.ps1 | 19 ++++++++-- .../Functions/EnvironmentContext.ps1 | 5 ++- .../Functions/ManagementGroups.ps1 | 37 ++++++++++++++++--- 3 files changed, 51 insertions(+), 10 deletions(-) diff --git a/scripts/deployments/E2E.ps1 b/scripts/deployments/E2E.ps1 index 2195d33d..5dc8d069 100644 --- a/scripts/deployments/E2E.ps1 +++ b/scripts/deployments/E2E.ps1 @@ -1,4 +1,4 @@ -#Requires -Modules powershell-yaml +#Requires -Modules Az, powershell-yaml . ".\Functions\EnvironmentContext.ps1" . ".\Functions\ManagementGroups.ps1" @@ -10,18 +10,27 @@ . ".\Functions\Subscriptions.ps1" $EnvironmentName = "CanadaESLZ-main" -$WorkingDirectory = "../.." +$WorkingDirectory = Resolve-Path "../.." + +# Replace the Tenant ID with the GUID for your Azure Active Directory instance. +# It can be found through https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/Overview +$AzureADTenantId = "343ddfdb-bef5-46d9-99cf-ed67d5948783" # Az Login -# TODO: Login +Connect-AzAccount ` + -UseDeviceAuthentication ` + -TenantId $AzureADTenantId # Set Azure Landing Zones Context $Context = New-EnvironmentContext -Environment $EnvironmentName -WorkingDirectory $WorkingDirectory # Deploy Management Groups Set-ManagementGroups ` + -Context $Context ` -ManagementGroupHierarchy $Context.ManagementGroupHierarchy +<# + # Deploy Roles Set-Roles ` -RolesDirectory $Context.RolesDirectory ` @@ -101,4 +110,6 @@ Set-HubNetwork-With-AzureFirewall ` Set-Subscriptions ` -Region "canadacentral" ` -SubscriptionIds $("4f9", "ec6") ` - -LogAnalyticsWorkspaceResourceId $LoggingConfiguration.LogAnalyticsWorkspaceResourceId \ No newline at end of file + -LogAnalyticsWorkspaceResourceId $LoggingConfiguration.LogAnalyticsWorkspaceResourceId + +#> \ No newline at end of file diff --git a/scripts/deployments/Functions/EnvironmentContext.ps1 b/scripts/deployments/Functions/EnvironmentContext.ps1 index ffd4cc85..99d8c431 100644 --- a/scripts/deployments/Functions/EnvironmentContext.ps1 +++ b/scripts/deployments/Functions/EnvironmentContext.ps1 @@ -24,7 +24,7 @@ function New-EnvironmentContext { # Create a new context object return [PSCustomObject]@{ - EnvironmentConfigurationYamlFilePath = $EnvironmentConfigurationYamlFilePath + WorkingDirectory = $WorkingDirectory RolesDirectory = "$WorkingDirectory/roles" @@ -41,5 +41,8 @@ function New-EnvironmentContext { # Identify the top level management group (the first child underneath Tenant Root Group) TopLevelManagementGroupId = $ManagementGroupHierarchy.children[0].id + + # TODO: Retrieve from common.yml + DeploymentRegion = "canadacentral" } } \ No newline at end of file diff --git a/scripts/deployments/Functions/ManagementGroups.ps1 b/scripts/deployments/Functions/ManagementGroups.ps1 index 3973ba7b..259f5a77 100644 --- a/scripts/deployments/Functions/ManagementGroups.ps1 +++ b/scripts/deployments/Functions/ManagementGroups.ps1 @@ -1,26 +1,53 @@ function Set-ManagementGroups { param ( + [Parameter(Mandatory = $true)] + $Context, + [Parameter(Mandatory = $true)] $ManagementGroupHierarchy ) + function Set-ChildManagementGroups { param ( + [Parameter(Mandatory = $true)] + $Context, + + [Parameter(Mandatory = $true)] + $RootManagementGroupId, + [Parameter(Mandatory = $true)] $ParentNode ) - foreach ($childNode in $ParentNode.children) { + ForEach ($childNode in $ParentNode.children) { $parentManagementGroupId = $ParentNode.id $childManagementGroupId = $childNode.id $childManagementGroupName = $childNode.name - + + $DeploymentParameters = @{ + topLevelManagementGroupName = $RootManagementGroupId + parentManagementGroupId = $parentManagementGroupId + childManagementGroupId = $childManagementGroupId + childManagementGroupName = $childManagementGroupName + } + Write-Output "Creating $childManagementGroupName [$childManagementGroupId] under $parentManagementGroupId" - # TODO: Add Azure PS deployment command + New-AzManagementGroupDeployment ` + -ManagementGroupId $parentManagementGroupId ` + -Location $Context.DeploymentRegion ` + -TemplateFile "$($Context.WorkingDirectory)/management-groups/structure-v2.bicep" ` + -TemplateParameterObject $DeploymentParameters - Set-ChildManagementGroups($childNode) + Set-ChildManagementGroups ` + -Context $Context ` + -RootManagementGroupId $RootManagementGroupId ` + -ParentNode $childNode } } - Set-ChildManagementGroups($ManagementGroupHierarchy) + Set-ChildManagementGroups ` + -Context $Context ` + -RootManagementGroupId $ManagementGroupHierarchy.id ` + -ParentNode $ManagementGroupHierarchy } \ No newline at end of file From 825f7308ee9f07040d7f26dabbe5d60aedcbd5d2 Mon Sep 17 00:00:00 2001 From: Senthuran Sivananthan Date: Fri, 29 Apr 2022 11:48:48 -0400 Subject: [PATCH 22/31] Create roles --- scripts/deployments/E2E.ps1 | 27 ++++++++++++++++++------- scripts/deployments/Functions/Roles.ps1 | 17 +++++++++++++--- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/scripts/deployments/E2E.ps1 b/scripts/deployments/E2E.ps1 index 5dc8d069..5b6ff177 100644 --- a/scripts/deployments/E2E.ps1 +++ b/scripts/deployments/E2E.ps1 @@ -16,6 +16,11 @@ $WorkingDirectory = Resolve-Path "../.." # It can be found through https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/Overview $AzureADTenantId = "343ddfdb-bef5-46d9-99cf-ed67d5948783" +$Features = @{ + DeployManagementGroups = $false + DeployRoles = $false +} + # Az Login Connect-AzAccount ` -UseDeviceAuthentication ` @@ -25,16 +30,24 @@ Connect-AzAccount ` $Context = New-EnvironmentContext -Environment $EnvironmentName -WorkingDirectory $WorkingDirectory # Deploy Management Groups -Set-ManagementGroups ` - -Context $Context ` - -ManagementGroupHierarchy $Context.ManagementGroupHierarchy +if ($Features.DeployManagementGroups) { + Set-ManagementGroups ` + -Context $Context ` + -ManagementGroupHierarchy $Context.ManagementGroupHierarchy +} + +# Deploy Roles +if ($Features.DeployRoles) { + Set-Roles ` + -Context $Context ` + -RolesDirectory $Context.RolesDirectory ` + -ManagementGroupId $Context.TopLevelManagementGroupId +} <# -# Deploy Roles -Set-Roles ` - -RolesDirectory $Context.RolesDirectory ` - -ManagementGroupId $Context.TopLevelManagementGroupId + + # Deploy Logging Set-Logging ` diff --git a/scripts/deployments/Functions/Roles.ps1 b/scripts/deployments/Functions/Roles.ps1 index fb73e1f6..2117f6f9 100644 --- a/scripts/deployments/Functions/Roles.ps1 +++ b/scripts/deployments/Functions/Roles.ps1 @@ -1,5 +1,8 @@ function Set-Roles { param ( + [Parameter(Mandatory = $true)] + $Context, + [Parameter(Mandatory = $true)] [String] $RolesDirectory, @@ -11,9 +14,17 @@ function Set-Roles { Write-Output "Deploying roles to management group: $ManagementGroupId" Write-Output "Deploying role definitions from $RolesDirectory" - foreach ($roleDefinition in Get-ChildItem -Path $RolesDirectory) { - Write-Output "Deploying $($roleDefinition.name)" + $DeploymentParameters = @{ + assignableMgId = $ManagementGroupId + } - # TODO: Add Azure PS deployment command + foreach ($roleDefinition in Get-ChildItem -Path $RolesDirectory) { + Write-Output "Deploying $($roleDefinition.FullName)" + + New-AzManagementGroupDeployment ` + -ManagementGroupId $ManagementGroupId ` + -Location $Context.DeploymentRegion ` + -TemplateFile $roleDefinition.FullName ` + -TemplateParameterObject $DeploymentParameters } } \ No newline at end of file From d293223f3cdf9b637e77d8da68b1adf7509aa5bd Mon Sep 17 00:00:00 2001 From: Senthuran Sivananthan Date: Fri, 29 Apr 2022 12:17:03 -0400 Subject: [PATCH 23/31] Be explicit on region --- config/variables/CanadaESLZ-main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/variables/CanadaESLZ-main.yml b/config/variables/CanadaESLZ-main.yml index 0d22f73e..d24941dd 100644 --- a/config/variables/CanadaESLZ-main.yml +++ b/config/variables/CanadaESLZ-main.yml @@ -58,7 +58,7 @@ variables: } # Logging - var-logging-region: $(deploymentRegion) + var-logging-region: canadacentral var-logging-managementGroupId: pubsecPlatformManagement var-logging-subscriptionId: bc0a4f9f-07fa-4284-b1bd-fbad38578d3a var-logging-configurationFileName: logging.parameters.json @@ -67,7 +67,7 @@ variables: var-logging-diagnosticSettingsforNetworkSecurityGroupsStoragePrefix: pubsecnsg # Hub Networking - var-hubnetwork-region: $(deploymentRegion) + var-hubnetwork-region: canadacentral var-hubnetwork-managementGroupId: pubsecPlatformConnectivity var-hubnetwork-subscriptionId: ed7f4eed-9010-4227-b115-2a5e37728f27 From 23c0185b19b8f8d15d81c76513295325ab41aec2 Mon Sep 17 00:00:00 2001 From: Senthuran Sivananthan Date: Fri, 29 Apr 2022 12:17:18 -0400 Subject: [PATCH 24/31] Create logging --- scripts/deployments/E2E.ps1 | 28 +++++++++++++++-------- scripts/deployments/Functions/Logging.ps1 | 21 +++++++++++++---- 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/scripts/deployments/E2E.ps1 b/scripts/deployments/E2E.ps1 index 5b6ff177..9b19392c 100644 --- a/scripts/deployments/E2E.ps1 +++ b/scripts/deployments/E2E.ps1 @@ -17,14 +17,21 @@ $WorkingDirectory = Resolve-Path "../.." $AzureADTenantId = "343ddfdb-bef5-46d9-99cf-ed67d5948783" $Features = @{ + PromptForLogin = $false DeployManagementGroups = $false DeployRoles = $false + DeployLogging = $false } +Write-Output "Features configured for deployment:" +$Features + # Az Login -Connect-AzAccount ` - -UseDeviceAuthentication ` - -TenantId $AzureADTenantId +if ($Features.PromptForLogin) { + Connect-AzAccount ` + -UseDeviceAuthentication ` + -TenantId $AzureADTenantId +} # Set Azure Landing Zones Context $Context = New-EnvironmentContext -Environment $EnvironmentName -WorkingDirectory $WorkingDirectory @@ -44,17 +51,20 @@ if ($Features.DeployRoles) { -ManagementGroupId $Context.TopLevelManagementGroupId } +# Deploy Logging +if ($Features.DeployLogging) { + Set-Logging ` + -Region $Context.Variables['var-logging-region'] ` + -ManagementGroupId $Context.Variables['var-logging-managementGroupId'] ` + -SubscriptionId $Context.Variables['var-logging-subscriptionId'] ` + -ConfigurationFilePath "$($Context.LoggingDirectory)/$($Context.Variables['var-logging-configurationFileName'])" +} + <# -# Deploy Logging -Set-Logging ` - -Region $Context.Variables['var-logging-region'] ` - -ManagementGroupId $Context.Variables['var-logging-managementGroupId'] ` - -SubscriptionId $Context.Variables['var-logging-subscriptionId'] ` - -ConfigurationFilePath "$($Context.LoggingDirectory)/$($Context.Variables['var-logging-configurationFileName'])" # Get Logging Configuration using logging configuration file & Azure environment $LoggingConfiguration = Get-LoggingConfiguration ` diff --git a/scripts/deployments/Functions/Logging.ps1 b/scripts/deployments/Functions/Logging.ps1 index fce4c713..fb5d1460 100644 --- a/scripts/deployments/Functions/Logging.ps1 +++ b/scripts/deployments/Functions/Logging.ps1 @@ -35,9 +35,22 @@ function Set-Logging { [String]$ConfigurationFilePath ) - # TODO: Add Azure PS deployment command - Write-Output "Moving Subscription ($SubscriptionId) to Management Group ($ManagementGroupId)" + Set-AzContext -Subscription $SubscriptionId - # TODO: Add Azure PS deployment command - Write-Output "Deploying $ConfigurationFilePath to $SubscriptionId in $Region" + 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 + } + + Write-Output "Deploying Logging to $SubscriptionId in $Region with $ConfigurationFilePath" + New-AzSubscriptionDeployment ` + -Name "main-$Region" ` + -Location $Region ` + -TemplateFile "$($Context.WorkingDirectory)/landingzones/lz-platform-logging/main.bicep" ` + -TemplateParameterFile $ConfigurationFilePath } \ No newline at end of file From dfd1432f9f48c085620eb0454e9a5b4f10a6cdd9 Mon Sep 17 00:00:00 2001 From: Senthuran Sivananthan Date: Fri, 29 Apr 2022 12:25:25 -0400 Subject: [PATCH 25/31] Retrieve LAW information from Azure --- scripts/deployments/Functions/Logging.ps1 | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/scripts/deployments/Functions/Logging.ps1 b/scripts/deployments/Functions/Logging.ps1 index fb5d1460..87c32473 100644 --- a/scripts/deployments/Functions/Logging.ps1 +++ b/scripts/deployments/Functions/Logging.ps1 @@ -9,14 +9,16 @@ function Get-LoggingConfiguration { $Configuration = Get-Content $ConfigurationFilePath | ConvertFrom-Json - # TODO: Retreive Log Analytics Workspace Resource Id & Workspace Id + $LogAnalyticsWorkspace = Get-AzOperationalInsightsWorkspace ` + -Name $Configuration.parameters.logAnalyticsWorkspaceName.value ` + -ResourceGroupName $Configuration.parameters.logAnalyticsResourceGroupName.value return [PSCustomObject]@{ ResourceGroup = $Configuration.parameters.logAnalyticsResourceGroupName.value LogAnalyticsWorkspaceName = $Configuration.parameters.logAnalyticsWorkspaceName.value LogRetentionInDays = $Configuration.parameters.logAnalyticsRetentionInDays.value - LogAnalyticsWorkspaceResourceId = "TODO" - LogAnalyticsWorkspaceId = "TODO" + LogAnalyticsWorkspaceResourceId = $LogAnalyticsWorkspace.ResourceId + LogAnalyticsWorkspaceId = $LogAnalyticsWorkspace.CustomerId } } From 062340c9e9b6d168e2a93c985e525b4e2c05894b Mon Sep 17 00:00:00 2001 From: Senthuran Sivananthan Date: Fri, 29 Apr 2022 12:44:29 -0400 Subject: [PATCH 26/31] Create policy definitions --- scripts/deployments/Functions/Policy.ps1 | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/scripts/deployments/Functions/Policy.ps1 b/scripts/deployments/Functions/Policy.ps1 index 5999c566..44a5118d 100644 --- a/scripts/deployments/Functions/Policy.ps1 +++ b/scripts/deployments/Functions/Policy.ps1 @@ -13,12 +13,22 @@ function Set-Policy-Definitions { $PolicyRuleFilePath = "$($_.FullName)/azurepolicy.rules.json" $PolicyParametersFilePath = "$($_.FullName)/azurepolicy.parameters.json" - Write-Output "Policy: $PolicyDefinitionName" - Write-Output "- Rule: $PolicyRuleFilePath" - Write-Output "- Parameters: $PolicyParametersFilePath" - Write-Output "- Config: $PolicyConfigFilePath" + $PolicyConfig = Get-Content $PolicyConfigFilePath | ConvertFrom-Json - # TODO: Add Azure PS deployment command + Write-Output "Policy: $PolicyDefinitionName" + Write-Output " - Rule: $PolicyRuleFilePath" + Write-Output " - Parameters: $PolicyParametersFilePath" + Write-Output " - Id: $PolicyDefinitionName" + Write-Output " - Display Name: $($PolicyConfig.name)" + Write-Output " - Mode: $($PolicyConfig.mode)" + + New-AzPolicyDefinition ` + -ManagementGroupName $ManagementGroupId ` + -Name $PolicyDefinitionName ` + -DisplayName $($PolicyConfig.name) ` + -Mode $PolicyConfig.mode ` + -Policy $PolicyRuleFilePath ` + -Parameter $PolicyParametersFilePath } } From d81878bdc24b8a407dc10ae16ac542db7d9eace0 Mon Sep 17 00:00:00 2001 From: Senthuran Sivananthan Date: Fri, 29 Apr 2022 13:48:14 -0400 Subject: [PATCH 27/31] Create policies & policy sets --- scripts/deployments/E2E.ps1 | 74 ++++++++++--------- .../Functions/EnvironmentContext.ps1 | 2 +- scripts/deployments/Functions/Logging.ps1 | 2 +- scripts/deployments/Functions/Policy.ps1 | 70 ++++++++++++++---- 4 files changed, 96 insertions(+), 52 deletions(-) diff --git a/scripts/deployments/E2E.ps1 b/scripts/deployments/E2E.ps1 index 9b19392c..528549ec 100644 --- a/scripts/deployments/E2E.ps1 +++ b/scripts/deployments/E2E.ps1 @@ -21,6 +21,7 @@ $Features = @{ DeployManagementGroups = $false DeployRoles = $false DeployLogging = $false + DeployPolicy = $false } Write-Output "Features configured for deployment:" @@ -60,47 +61,50 @@ if ($Features.DeployLogging) { -ConfigurationFilePath "$($Context.LoggingDirectory)/$($Context.Variables['var-logging-configurationFileName'])" } -<# - - +if ($Features.DeployPolicy) { + # Get Logging information using logging config file + $LoggingConfiguration = Get-LoggingConfiguration ` + -ConfigurationFilePath "$($Context.LoggingDirectory)/$($Context.Variables['var-logging-configurationFileName'])" ` + -SubscriptionId $Context.Variables['var-logging-subscriptionId'] + # Custom Policy Definitions + Set-Policy-Definitions ` + -PolicyDefinitionsDirectory $Context.PolicyCustomDefinitionDirectory ` + -ManagementGroupId $Context.TopLevelManagementGroupId + # Custom Policy Set Definitions + Set-PolicySet-Defintions ` + -Context $Context ` + -PolicySetDefinitionsDirectory $Context.PolicySetCustomDefinitionDirectory ` + -ManagementGroupId $Context.TopLevelManagementGroupId ` + -PolicySetDefinitionNames $('AKS', 'DefenderForCloud', 'LogAnalytics', 'Network', 'DNSPrivateEndpoints', 'Tags') -# Get Logging Configuration using logging configuration file & Azure environment -$LoggingConfiguration = Get-LoggingConfiguration ` - -ConfigurationFilePath "$($Context.LoggingDirectory)/$($Context.Variables['var-logging-configurationFileName'])" ` - -SubscriptionId $Context.Variables['var-logging-subscriptionId'] - -# Deploy Policies - -## Custom Policy Definitions -Set-Policy-Definitions ` - -PolicyDefinitionsDirectory $Context.PolicyCustomDefinitionDirectory ` - -ManagementGroupId $Context.TopLevelManagementGroupId + # Built In Policy Set Assignments + Set-PolicySet-Assignments ` + -Context $Context ` + -PolicySetAssignmentsDirectory $Context.PolicySetBuiltInAssignmentsDirectory ` + -PolicySetAssignmentManagementGroupId $Context.TopLevelManagementGroupId ` + -PolicySetAssignmentNames $('asb', 'nist80053r4', 'nist80053r5', 'pbmm', 'cis-msft-130', 'fedramp-moderate', 'hitrust-hipaa', 'location') ` + -LogAnalyticsWorkspaceResourceGroupName $LoggingConfiguration.ResourceGroupName ` + -LogAnalyticsWorkspaceResourceId $LoggingConfiguration.LogAnalyticsWorkspaceResourceId ` + -LogAnalyticsWorkspaceId $LoggingConfiguration.LogAnalyticsWorkspaceId ` + -LogAnalyticsWorkspaceRetentionInDays $LoggingConfiguration.LogRetentionInDays + + # Custom Policy Sets Assignments + Set-PolicySet-Assignments ` + -Context $Context ` + -PolicySetAssignmentsDirectory $Context.PolicySetCustomAssignmentsDirectory ` + -PolicySetAssignmentManagementGroupId $Context.TopLevelManagementGroupId ` + -PolicySetAssignmentNames $('AKS', 'DefenderForCloud', 'LogAnalytics', 'Network', 'Tags') ` + -LogAnalyticsWorkspaceResourceGroupName $LoggingConfiguration.ResourceGroupName ` + -LogAnalyticsWorkspaceResourceId $LoggingConfiguration.LogAnalyticsWorkspaceResourceId ` + -LogAnalyticsWorkspaceId $LoggingConfiguration.LogAnalyticsWorkspaceId ` + -LogAnalyticsWorkspaceRetentionInDays $LoggingConfiguration.LogRetentionInDays +} -## Custom Policy Set Definitions -Set-PolicySet-Defintions ` - -PolicySetDefinitionsDirectory $Context.PolicySetCustomDefinitionDirectory ` - -ManagementGroupId $Context.TopLevelManagementGroupId ` - -PolicySetDefinitionNames $('AKS', 'DefenderForCloud', 'LogAnalytics', 'Network', 'DNSPrivateEndpoints', 'Tags') +<# -## Built In Policy Set Assignments -Set-PolicySet-Assignments ` - -PolicySetAssignmentsDirectory $Context.PolicySetBuiltInAssignmentsDirectory ` - -PolicySetAssignmentManagementGroupId $Context.TopLevelManagementGroupId ` - -PolicySetAssignmentNames $('asb', 'nist80053r4', 'nist80053r5', 'pbmm', 'cis-msft-130', 'fedramp-moderate', 'hitrust-hipaa', 'location') ` - -LogAnalyticsWorkspaceResourceId $LoggingConfiguration.LogAnalyticsWorkspaceResourceId ` - -LogAnalyticsWorkspaceId $LoggingConfiguration.LogAnalyticsWorkspaceId ` - -LogAnalyticsWorkspaceRetentionInDays $LoggingConfiguration.LogRetentionInDays -#Custom Policy Sets Assignments -Set-PolicySet-Assignments ` - -PolicySetAssignmentsDirectory $Context.PolicySetCustomAssignmentsDirectory ` - -PolicySetAssignmentManagementGroupId $Context.TopLevelManagementGroupId ` - -PolicySetAssignmentNames $('AKS', 'DefenderForCloud', 'LogAnalytics', 'Network', 'Tags') ` - -LogAnalyticsWorkspaceResourceId $LoggingConfiguration.LogAnalyticsWorkspaceResourceId ` - -LogAnalyticsWorkspaceId $LoggingConfiguration.LogAnalyticsWorkspaceId ` - -LogAnalyticsWorkspaceRetentionInDays $LoggingConfiguration.LogRetentionInDays # Hub Networking with NVA Set-HubNetwork-With-NVA ` diff --git a/scripts/deployments/Functions/EnvironmentContext.ps1 b/scripts/deployments/Functions/EnvironmentContext.ps1 index 99d8c431..2a6b66ac 100644 --- a/scripts/deployments/Functions/EnvironmentContext.ps1 +++ b/scripts/deployments/Functions/EnvironmentContext.ps1 @@ -30,7 +30,7 @@ function New-EnvironmentContext { PolicyCustomDefinitionDirectory = "$PolicyDirectory/custom/definitions/policy" PolicySetCustomDefinitionDirectory = "$PolicyDirectory/custom/definitions/policyset" - PolicySetCustomAssignmentsDirectory = "$PolicyDirectory/custom/assignments/policyset" + PolicySetCustomAssignmentsDirectory = "$PolicyDirectory/custom/assignments" PolicySetBuiltInAssignmentsDirectory = "$PolicyDirectory/builtin/assignments" LoggingDirectory = "$WorkingDirectory/config/logging/$Environment" diff --git a/scripts/deployments/Functions/Logging.ps1 b/scripts/deployments/Functions/Logging.ps1 index 87c32473..fc9e079c 100644 --- a/scripts/deployments/Functions/Logging.ps1 +++ b/scripts/deployments/Functions/Logging.ps1 @@ -14,7 +14,7 @@ function Get-LoggingConfiguration { -ResourceGroupName $Configuration.parameters.logAnalyticsResourceGroupName.value return [PSCustomObject]@{ - ResourceGroup = $Configuration.parameters.logAnalyticsResourceGroupName.value + ResourceGroupName = $Configuration.parameters.logAnalyticsResourceGroupName.value LogAnalyticsWorkspaceName = $Configuration.parameters.logAnalyticsWorkspaceName.value LogRetentionInDays = $Configuration.parameters.logAnalyticsRetentionInDays.value LogAnalyticsWorkspaceResourceId = $LogAnalyticsWorkspace.ResourceId diff --git a/scripts/deployments/Functions/Policy.ps1 b/scripts/deployments/Functions/Policy.ps1 index 44a5118d..32d208f8 100644 --- a/scripts/deployments/Functions/Policy.ps1 +++ b/scripts/deployments/Functions/Policy.ps1 @@ -34,6 +34,9 @@ function Set-Policy-Definitions { function Set-PolicySet-Defintions { param( + [Parameter(Mandatory = $true)] + $Context, + [Parameter(Mandatory = $true)] [String] $PolicySetDefinitionsDirectory, @@ -45,25 +48,38 @@ function Set-PolicySet-Defintions { ) foreach ($policySetDefinitionName in $PolicySetDefinitionNames) { - Write-Output "Policy set definition: $policySetDefinitionName" - $PolicySetDefinitionFilePath = "$($PolicySetDefinitionsDirectory)/$($policySetDefinitionName).bicep" $PolicySetDefinitionParametersFilePath = "$($PolicySetDefinitionsDirectory)/$($policySetDefinitionName).parameters.json" - Write-Output "Policy Set: $policySetDefinitionName" - Write-Output "- Definition: $PolicySetDefinitionFilePath" - Write-Output "- Parameters: $PolicySetDefinitionParametersFilePath" + # Replace templated parameters & create temp file for deployment + $ParametersContent = Get-Content $PolicySetDefinitionParametersFilePath + $ParametersContent = $ParametersContent -Replace '{{var-topLevelManagementGroupName}}', $ManagementGroupId - # TODO: Add logic to load logging configuration + $PopulatedParametersFilePath = "$($PolicySetDefinitionsDirectory)/$($policySetDefinitionName)-populated.parameters.json" + $ParametersContent | Set-Content -Path $PopulatedParametersFilePath - # TODO: Add logic to replace templated parameters - - # TODO: Add Azure PS deployment command + Write-Output "Policy Set: $policySetDefinitionName" + Write-Output " - Definition: $PolicySetDefinitionFilePath" + Write-Output " - Parameters: $PolicySetDefinitionParametersFilePath" + Write-Output " - Populated (temp): $PopulatedParametersFilePath" + + # Deploy Policy Set + New-AzManagementGroupDeployment ` + -ManagementGroupId $ManagementGroupId ` + -Location $Context.DeploymentRegion ` + -TemplateFile $PolicySetDefinitionFilePath ` + -TemplateParameterFile $PopulatedParametersFilePath + + # Remove temporary file + Remove-Item $PopulatedParametersFilePath } } function Set-PolicySet-Assignments { param( + [Parameter(Mandatory = $true)] + $Context, + [Parameter(Mandatory = $true)] [String] $PolicySetAssignmentsDirectory, @@ -73,6 +89,9 @@ function Set-PolicySet-Assignments { [Parameter(Mandatory = $true)] [String[]] $PolicySetAssignmentNames, + [Parameter(Mandatory = $true)] + [String] $LogAnalyticsWorkspaceResourceGroupName, + [Parameter(Mandatory = $true)] [String] $LogAnalyticsWorkspaceResourceId, @@ -86,6 +105,8 @@ function Set-PolicySet-Assignments { foreach ($policySetAssignmentName in $PolicySetAssignmentNames) { Write-Output "Policy Set assignment Name: $($policySetAssignmentName)" + $PolicySetAssignmentFilePath = "$($PolicySetAssignmentsDirectory)/$($policySetAssignmentName).bicep" + $DefaultPolicyParameterFilePath = "$PolicySetAssignmentsDirectory/$policySetAssignmentName.parameters.json" $AssignmentScopeParameterFilePath = "$PolicySetAssignmentsDirectory/$policySetAssignmentName-$PolicySetAssignmentManagementGroupId.parameters.json" @@ -98,13 +119,32 @@ function Set-PolicySet-Assignments { $PolicySetParameterFilePath = $DefaultPolicyParameterFilePath } - Write-Output "Policy: $policy" - Write-Output "- Definition: $PolicySetAssignmentsDirectory/$policySetAssignmentName.bicep" - Write-Output "- Parameters: $PolicySetParameterFilePath" - - # TODO: Add logic to replace templated parameters + # Replace templated parameters & create temp file for deployment + $ParametersContent = Get-Content $PolicySetParameterFilePath + $ParametersContent = $ParametersContent -Replace '{{var-topLevelManagementGroupName}}', $Context.TopLevelManagementGroupId + $ParametersContent = $ParametersContent -Replace '{{var-logging-logAnalyticsWorkspaceResourceId}}', $LogAnalyticsWorkspaceResourceId + $ParametersContent = $ParametersContent -Replace '{{var-logging-logAnalyticsWorkspaceId}}', $LogAnalyticsWorkspaceId + $ParametersContent = $ParametersContent -Replace '{{var-logging-logAnalyticsResourceGroupName}}', $LogAnalyticsWorkspaceResourceGroupName + $ParametersContent = $ParametersContent -Replace '{{var-logging-logAnalyticsRetentionInDays}}', $LogAnalyticsWorkspaceRetentionInDays + $ParametersContent = $ParametersContent -Replace '{{var-policyAssignmentManagementGroupId}}', $PolicySetAssignmentManagementGroupId + $ParametersContent = $ParametersContent -Replace '{{var-logging-diagnosticSettingsforNetworkSecurityGroupsStoragePrefix}}', $Context.Variables['var-logging-diagnosticSettingsforNetworkSecurityGroupsStoragePrefix'] - # TODO: Add Azure PS deployment command + $PopulatedParametersFilePath = "$($PolicySetAssignmentsDirectory)/$($policySetAssignmentName)-populated.parameters.json" + $ParametersContent | Set-Content -Path $PopulatedParametersFilePath + Write-Output "Policy: $policy" + Write-Output " - Definition: $PolicySetAssignmentFilePath" + Write-Output " - Parameters: $PolicySetParameterFilePath" + Write-Output " - Populated (temp): $PopulatedParametersFilePath" + + # Deploy Policy Set + New-AzManagementGroupDeployment ` + -ManagementGroupId $PolicySetAssignmentManagementGroupId ` + -Location $Context.DeploymentRegion ` + -TemplateFile $PolicySetAssignmentFilePath ` + -TemplateParameterFile $PopulatedParametersFilePath + + # Remove temporary file + Remove-Item $PopulatedParametersFilePath } } From 954aa92b96a0c043e51591daf03a1746b3cb6971 Mon Sep 17 00:00:00 2001 From: Senthuran Sivananthan Date: Fri, 29 Apr 2022 15:04:50 -0400 Subject: [PATCH 28/31] Ensure context is to the logging subscription --- scripts/deployments/Functions/Logging.ps1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/deployments/Functions/Logging.ps1 b/scripts/deployments/Functions/Logging.ps1 index fc9e079c..c90dbaba 100644 --- a/scripts/deployments/Functions/Logging.ps1 +++ b/scripts/deployments/Functions/Logging.ps1 @@ -9,6 +9,8 @@ function Get-LoggingConfiguration { $Configuration = Get-Content $ConfigurationFilePath | ConvertFrom-Json + Set-AzContext -Subscription $SubscriptionId + $LogAnalyticsWorkspace = Get-AzOperationalInsightsWorkspace ` -Name $Configuration.parameters.logAnalyticsWorkspaceName.value ` -ResourceGroupName $Configuration.parameters.logAnalyticsResourceGroupName.value From 57c6c26e8aa36664bafb7e4dbd795eccf1dfdcdf Mon Sep 17 00:00:00 2001 From: Senthuran Sivananthan Date: Fri, 29 Apr 2022 15:05:38 -0400 Subject: [PATCH 29/31] Create Hub Networking with NVA --- scripts/deployments/E2E.ps1 | 26 +++-- .../Functions/HubNetworkWithNVA.ps1 | 100 ++++++++++++++++-- 2 files changed, 113 insertions(+), 13 deletions(-) diff --git a/scripts/deployments/E2E.ps1 b/scripts/deployments/E2E.ps1 index 528549ec..3519fea9 100644 --- a/scripts/deployments/E2E.ps1 +++ b/scripts/deployments/E2E.ps1 @@ -22,6 +22,7 @@ $Features = @{ DeployRoles = $false DeployLogging = $false DeployPolicy = $false + DeployHubNetworkWithNVA = $false } Write-Output "Features configured for deployment:" @@ -61,6 +62,7 @@ if ($Features.DeployLogging) { -ConfigurationFilePath "$($Context.LoggingDirectory)/$($Context.Variables['var-logging-configurationFileName'])" } +# Deploy Policy if ($Features.DeployPolicy) { # Get Logging information using logging config file $LoggingConfiguration = Get-LoggingConfiguration ` @@ -102,17 +104,27 @@ if ($Features.DeployPolicy) { -LogAnalyticsWorkspaceRetentionInDays $LoggingConfiguration.LogRetentionInDays } +# Deploy Hub Networking with NVA +if ($Features.DeployHubNetworkWithNVA) { + # Get Logging information using logging config file + $LoggingConfiguration = Get-LoggingConfiguration ` + -ConfigurationFilePath "$($Context.LoggingDirectory)/$($Context.Variables['var-logging-configurationFileName'])" ` + -SubscriptionId $Context.Variables['var-logging-subscriptionId'] + + Set-HubNetwork-With-NVA ` + -Context $Context ` + -Region $Context.Variables['var-hubnetwork-region'] ` + -ManagementGroupId $Context.Variables['var-hubnetwork-managementGroupId'] ` + -SubscriptionId $Context.Variables['var-hubnetwork-subscriptionId'] ` + -ConfigurationFilePath "$($Context.NetworkingDirectory)/$($Context.Variables['var-hubnetwork-nva-configurationFileName'])" ` + -LogAnalyticsWorkspaceResourceId $LoggingConfiguration.LogAnalyticsWorkspaceResourceId +} + <# -# Hub Networking with NVA -Set-HubNetwork-With-NVA ` - -Region $Context.Variables['var-hubnetwork-region'] ` - -ManagementGroupId $Context.Variables['var-hubnetwork-managementGroupId'] ` - -SubscriptionId $Context.Variables['var-hubnetwork-subscriptionId'] ` - -ConfigurationFilePath "$($Context.NetworkingDirectory)/$($Context.Variables['var-hubnetwork-nva-configurationFileName'])" ` - -LogAnalyticsWorkspaceResourceId $LoggingConfiguration.LogAnalyticsWorkspaceResourceId + # Hub Networking with Azure Firewall Set-AzureFirewallPolicy ` diff --git a/scripts/deployments/Functions/HubNetworkWithNVA.ps1 b/scripts/deployments/Functions/HubNetworkWithNVA.ps1 index ac315bbd..55482fa4 100644 --- a/scripts/deployments/Functions/HubNetworkWithNVA.ps1 +++ b/scripts/deployments/Functions/HubNetworkWithNVA.ps1 @@ -1,5 +1,8 @@ function Set-HubNetwork-With-NVA { param ( + [Parameter(Mandatory = $true)] + $Context, + [Parameter(Mandatory = $true)] [String]$Region, @@ -16,15 +19,100 @@ function Set-HubNetwork-With-NVA { [String]$LogAnalyticsWorkspaceResourceId ) - # TODO: Load networking configuration and check if Log Analytics Workspace Id is provided. Otherwise set it. + Set-AzContext -Subscription $SubscriptionId + + # 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 - # TODO: Add Azure PS deployment command 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 + } - # TODO: Add Azure PS deployment command - Write-Output "Deploying $ConfigurationFilePath to $SubscriptionId in $Region" + Write-Output "Deploying $PopulatedParametersFilePath to $SubscriptionId in $Region" + New-AzSubscriptionDeployment ` + -Name "main-$Region" ` + -Location $Region ` + -TemplateFile "$($Context.WorkingDirectory)/landingzones/lz-platform-connectivity-hub-nva/main.bicep" ` + -TemplateParameterFile $PopulatedParametersFilePath ` + -Verbose - # TODO: Check if Private DNS Zones are managed in the Hub. If so, enable Private DNS Zones policy assignment + #region Check if Private DNS Zones are managed in the Hub. If so, enable Private DNS Zones policy assignment + if ($Configuration.parameters.privateDnsZones.value.enabled -eq $true) { + $PolicyAssignmentFilePath = "$($Context.PolicySetCustomAssignmentsDirectory)/DNSPrivateEndpoints.bicep" + + Write-Output "Hub Network will manage private dns zones, creating Azure Policy assignment to automatically create Private Endpoint DNS Zones." + Write-Output "Deploying policy assignment using $PolicyAssignmentFilePath" + + $Parameters = @{ + policyAssignmentManagementGroupId = $Context.TopLevelManagementGroupId + policyDefinitionManagementGroupId = $Context.TopLevelManagementGroupId + privateDNSZoneSubscriptionId = $SubscriptionId + privateDNSZoneResourceGroupName = $Configuration.parameters.privateDnsZones.value.resourceGroupName + } + + New-AzManagementGroupDeployment ` + -ManagementGroupId $Context.TopLevelManagementGroupId ` + -Location $Context.DeploymentRegion ` + -TemplateFile $PolicyAssignmentFilePath ` + -TemplateParameterObject $Parameters + } + else { + Write-Output "Hub Network will not manage private dns zones. Azure Policy assignment will be skipped." + } + #endregion + + #region Check if DDOS Standard is deployed in the Hub. If so, enable DDOS Standard policy assignment + if ($Configuration.parameters.ddosStandard.value.enabled -eq $true) { + $DDoSPlan = Get-AzDdosProtectionPlan ` + -ResourceGroupName $Configuration.parameters.ddosStandard.value.resourceGroupName ` + -Name $Configuration.parameters.ddosStandard.value.planName + + $PolicyAssignmentFilePath = "$($Context.PolicySetCustomAssignmentsDirectory)/DDoS.bicep" + + Write-Output "DDoS Standard is enabled, creating Azure Policy assignment to protect for all Virtual Networks in '$($Context.TopLevelManagementGroupId)' management group." + Write-Output "Deploying policy assignment using $PolicyAssignmentFilePath" + + $Parameters = @{ + policyAssignmentManagementGroupId = $Context.TopLevelManagementGroupId + policyDefinitionManagementGroupId = $Context.TopLevelManagementGroupId + ddosStandardPlanId = $DDoSPlan.Id + } + + New-AzManagementGroupDeployment ` + -ManagementGroupId $Context.TopLevelManagementGroupId ` + -Location $Context.DeploymentRegion ` + -TemplateFile $PolicyAssignmentFilePath ` + -TemplateParameterObject $Parameters + } + else { + Write-Output "DDoS Standard is not enabled. Azure Policy assignment will be skipped." + } + #endregion - # TODO: Check if DDOS Standard is deployed in the Hub. If so, enable DDOS Standard policy assignment + Remove-Item $PopulatedParametersFilePath } \ No newline at end of file From 36add77c2ed7ea665aaa9b16f73c226e8400744d Mon Sep 17 00:00:00 2001 From: Senthuran Sivananthan Date: Fri, 29 Apr 2022 15:44:53 -0400 Subject: [PATCH 30/31] Create Hub Networking with Azure Firewall --- scripts/deployments/E2E.ps1 | 64 ++++++--- .../Functions/HubNetworkWithAzureFirewall.ps1 | 129 ++++++++++++++++-- 2 files changed, 159 insertions(+), 34 deletions(-) diff --git a/scripts/deployments/E2E.ps1 b/scripts/deployments/E2E.ps1 index 3519fea9..4cb83f77 100644 --- a/scripts/deployments/E2E.ps1 +++ b/scripts/deployments/E2E.ps1 @@ -17,12 +17,26 @@ $WorkingDirectory = Resolve-Path "../.." $AzureADTenantId = "343ddfdb-bef5-46d9-99cf-ed67d5948783" $Features = @{ + # Prompt to login to Azure AD and set the context for Azure deployments PromptForLogin = $false + + # Resource Organization DeployManagementGroups = $false + + # Access Control DeployRoles = $false + + # Logging DeployLogging = $false + + # Guardrail & Compliance DeployPolicy = $false + + # Hub Networking - With Network Virtual Appliance DeployHubNetworkWithNVA = $false + + # Hub Networking - With Azure Firewall + DeployHubNetworkWithAzureFirewall = $false } Write-Output "Features configured for deployment:" @@ -120,30 +134,36 @@ if ($Features.DeployHubNetworkWithNVA) { -LogAnalyticsWorkspaceResourceId $LoggingConfiguration.LogAnalyticsWorkspaceResourceId } -<# - - - +# Hub Networking with Azure Firewall +if ($Features.DeployHubNetworkWithAzureFirewall) { + # 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 Azure Firewall Policy + Set-AzureFirewallPolicy ` + -Region $Context.Variables['var-hubnetwork-region'] ` + -SubscriptionId $Context.Variables['var-hubnetwork-subscriptionId'] ` + -ConfigurationFilePath "$($Context.NetworkingDirectory)/$($Context.Variables['var-hubnetwork-azfwPolicy-configurationFileName'])" + + # Retrieve Azure Firewall Policy + $AzureFirewallPolicyConfiguration = Get-AzureFirewallPolicy ` + -SubscriptionId $Context.Variables['var-hubnetwork-subscriptionId'] ` + -ConfigurationFilePath "$($Context.NetworkingDirectory)/$($Context.Variables['var-hubnetwork-azfwPolicy-configurationFileName'])" + + # Create Hub Networking with Azure Firewall + Set-HubNetwork-With-AzureFirewall ` + -Context $Context ` + -Region $Context.Variables['var-hubnetwork-region'] ` + -ManagementGroupId $Context.Variables['var-hubnetwork-managementGroupId'] ` + -SubscriptionId $Context.Variables['var-hubnetwork-subscriptionId'] ` + -ConfigurationFilePath "$($Context.NetworkingDirectory)/$($Context.Variables['var-hubnetwork-azfw-configurationFileName'])" ` + -AzureFirewallPolicyResourceId $AzureFirewallPolicyConfiguration.AzureFirewallPolicyResourceId ` + -LogAnalyticsWorkspaceResourceId $LoggingConfiguration.LogAnalyticsWorkspaceResourceId +} -# Hub Networking with Azure Firewall -Set-AzureFirewallPolicy ` - -Region $Context.Variables['var-hubnetwork-region'] ` - -SubscriptionId $Context.Variables['var-hubnetwork-subscriptionId'] ` - -ConfigurationFilePath "$($Context.NetworkingDirectory)/$($Context.Variables['var-hubnetwork-azfwPolicy-configurationFileName'])" - -# Retrieve Azure Firewall Configuration -$AzureFirewallConfiguration = Get-AzureFirewallPolicy ` - -SubscriptionId $Context.Variables['var-hubnetwork-subscriptionId'] ` - -ConfigurationFilePath "$($Context.NetworkingDirectory)/$($Context.Variables['var-hubnetwork-azfwPolicy-configurationFileName'])" - -Set-HubNetwork-With-AzureFirewall ` - -Region $Context.Variables['var-hubnetwork-region'] ` - -ManagementGroupId $Context.Variables['var-hubnetwork-managementGroupId'] ` - -SubscriptionId $Context.Variables['var-hubnetwork-subscriptionId'] ` - -ConfigurationFilePath "$($Context.NetworkingDirectory)/$($Context.Variables['var-hubnetwork-azfw-configurationFileName'])" ` - -AzureFirewallPolicyResourceId $AzureFirewallConfiguration.AzureFirewallPolicyResourceId ` - -LogAnalyticsWorkspaceResourceId $LoggingConfiguration.LogAnalyticsWorkspaceResourceId +<# # Subscriptions Set-Subscriptions ` diff --git a/scripts/deployments/Functions/HubNetworkWithAzureFirewall.ps1 b/scripts/deployments/Functions/HubNetworkWithAzureFirewall.ps1 index 3833beb4..a6af024c 100644 --- a/scripts/deployments/Functions/HubNetworkWithAzureFirewall.ps1 +++ b/scripts/deployments/Functions/HubNetworkWithAzureFirewall.ps1 @@ -7,12 +7,16 @@ function Get-AzureFirewallPolicy { [String]$SubscriptionId ) + Set-AzContext -Subscription $SubscriptionId + $Configuration = Get-Content $ConfigurationFilePath | ConvertFrom-Json - # TODO: Retreive Azure Firewall Policy Id + $policy = Get-AzFirewallPolicy ` + -ResourceGroupName $Configuration.parameters.resourceGroupName.value ` + -Name $Configuration.parameters.policyName.value return [PSCustomObject]@{ - AzureFirewallPolicyResourceId = "TODO" + AzureFirewallPolicyResourceId = $policy.Id } } @@ -28,12 +32,22 @@ function Set-AzureFirewallPolicy { [String]$ConfigurationFilePath ) - # TODO: Add Azure PS deployment command - Write-Output "Deploying $ConfigurationFilePath to $SubscriptionId in $Region" + Set-AzContext -Subscription $SubscriptionId + + Write-Output "Deploying to $SubscriptionId in $Region using $ConfigurationFilePath" + + New-AzSubscriptionDeployment ` + -Name "main-$Region" ` + -Location $Region ` + -TemplateFile "$($Context.WorkingDirectory)/landingzones/lz-platform-connectivity-hub-azfw/main-azfw-policy.bicep" ` + -TemplateParameterFile $ConfigurationFilePath } function Set-HubNetwork-With-AzureFirewall { param ( + [Parameter(Mandatory = $true)] + $Context, + [Parameter(Mandatory = $true)] [String]$Region, @@ -53,17 +67,108 @@ function Set-HubNetwork-With-AzureFirewall { [String]$LogAnalyticsWorkspaceResourceId ) - # TODO: Load networking configuration and check if Log Analytics Workspace Id is provided. Otherwise set it. + Set-AzContext -Subscription $SubscriptionId - # TODO: Load networking configuration and check if Firewall Policy is provided. Otherwise set it. + # Load networking configuration + $Configuration = Get-Content $ConfigurationFilePath | ConvertFrom-Json -Depth 100 - # TODO: Add Azure PS deployment command - Write-Output "Moving Subscription ($SubscriptionId) to Management Group ($ManagementGroupId)" + #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 - # TODO: Add Azure PS deployment command - Write-Output "Deploying $ConfigurationFilePath to $SubscriptionId in $Region" + #region Check if Azure Firewall Policy Id is provided. Otherwise set it. + $AzureFirewallPolicyResourceIdInFile = $Configuration.parameters.hub.value.azureFirewall | Get-Member -Name firewallPolicyId + + if ($null -eq $AzureFirewallPolicyResourceIdInFile -or $Configuration.parameters.hub.value.azureFirewall.firewallPolicyId -eq "") { + $Configuration.parameters.hub.value.azureFirewall | Add-Member -MemberType NoteProperty -Name firewallPolicyId -Value $AzureFirewallPolicyResourceId -Force + } + #endregion + + $PopulatedParametersFilePath = $ConfigurationFilePath.Split('.')[0] + '-populated.json' - # TODO: Check if Private DNS Zones are managed in the Hub. If so, enable Private DNS Zones policy assignment + 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 + } + + Write-Output "Deploying $PopulatedParametersFilePath to $SubscriptionId in $Region" + New-AzSubscriptionDeployment ` + -Name "main-$Region" ` + -Location $Region ` + -TemplateFile "$($Context.WorkingDirectory)/landingzones/lz-platform-connectivity-hub-azfw/main.bicep" ` + -TemplateParameterFile $PopulatedParametersFilePath ` + -Verbose + + #region Check if Private DNS Zones are managed in the Hub. If so, enable Private DNS Zones policy assignment + if ($Configuration.parameters.privateDnsZones.value.enabled -eq $true) { + $PolicyAssignmentFilePath = "$($Context.PolicySetCustomAssignmentsDirectory)/DNSPrivateEndpoints.bicep" + + Write-Output "Hub Network will manage private dns zones, creating Azure Policy assignment to automatically create Private Endpoint DNS Zones." + Write-Output "Deploying policy assignment using $PolicyAssignmentFilePath" + + $Parameters = @{ + policyAssignmentManagementGroupId = $Context.TopLevelManagementGroupId + policyDefinitionManagementGroupId = $Context.TopLevelManagementGroupId + privateDNSZoneSubscriptionId = $SubscriptionId + privateDNSZoneResourceGroupName = $Configuration.parameters.privateDnsZones.value.resourceGroupName + } + + New-AzManagementGroupDeployment ` + -ManagementGroupId $Context.TopLevelManagementGroupId ` + -Location $Context.DeploymentRegion ` + -TemplateFile $PolicyAssignmentFilePath ` + -TemplateParameterObject $Parameters + } + else { + Write-Output "Hub Network will not manage private dns zones. Azure Policy assignment will be skipped." + } + #endregion + + #region Check if DDOS Standard is deployed in the Hub. If so, enable DDOS Standard policy assignment + if ($Configuration.parameters.ddosStandard.value.enabled -eq $true) { + $DDoSPlan = Get-AzDdosProtectionPlan ` + -ResourceGroupName $Configuration.parameters.ddosStandard.value.resourceGroupName ` + -Name $Configuration.parameters.ddosStandard.value.planName + + $PolicyAssignmentFilePath = "$($Context.PolicySetCustomAssignmentsDirectory)/DDoS.bicep" + + Write-Output "DDoS Standard is enabled, creating Azure Policy assignment to protect for all Virtual Networks in '$($Context.TopLevelManagementGroupId)' management group." + Write-Output "Deploying policy assignment using $PolicyAssignmentFilePath" + + $Parameters = @{ + policyAssignmentManagementGroupId = $Context.TopLevelManagementGroupId + policyDefinitionManagementGroupId = $Context.TopLevelManagementGroupId + ddosStandardPlanId = $DDoSPlan.Id + } + + New-AzManagementGroupDeployment ` + -ManagementGroupId $Context.TopLevelManagementGroupId ` + -Location $Context.DeploymentRegion ` + -TemplateFile $PolicyAssignmentFilePath ` + -TemplateParameterObject $Parameters + } + else { + Write-Output "DDoS Standard is not enabled. Azure Policy assignment will be skipped." + } + #endregion - # TODO: Check if DDOS Standard is deployed in the Hub. If so, enable DDOS Standard policy assignment + Remove-Item $PopulatedParametersFilePath } \ No newline at end of file From 2a8e0817757af72ad2e85abfbf7eb31e25484b83 Mon Sep 17 00:00:00 2001 From: Senthuran Sivananthan Date: Fri, 29 Apr 2022 16:24:58 -0400 Subject: [PATCH 31/31] Update notes --- scripts/deployments/Functions/Subscriptions.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/deployments/Functions/Subscriptions.ps1 b/scripts/deployments/Functions/Subscriptions.ps1 index d3afbd65..4c0d0524 100644 --- a/scripts/deployments/Functions/Subscriptions.ps1 +++ b/scripts/deployments/Functions/Subscriptions.ps1 @@ -1,7 +1,7 @@ function Set-Subscriptions { param ( [Parameter(Mandatory = $true)] - [String]$Region, + [String] $Region, [Parameter(Mandatory = $true)] [String[]] $SubscriptionIds, @@ -19,7 +19,7 @@ function Set-Subscriptions { # TODO: Parse the file name to determine archetype, region and subscription id - # TODO: Load networking configuration and check if Log Analytics Workspace Id is provided. Otherwise set it. + # TODO: Load subscription configuration and check if Log Analytics Workspace Id is provided. Otherwise set it. # TODO: Add Azure PS deployment command }