Skip to content

Commit

Permalink
Configurable management group hierarchy (Azure#186)
Browse files Browse the repository at this point in the history
Implement configurable management group hierarchy
  • Loading branch information
skeeler authored Feb 27, 2022
1 parent 9a141f7 commit c62dcfc
Show file tree
Hide file tree
Showing 17 changed files with 442 additions and 59 deletions.
2 changes: 2 additions & 0 deletions .pipelines/management-groups.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ stages:
steps:
- checkout: self

- template: templates/steps/load-variables.yml

- template: templates/steps/show-variables.yml
parameters:
json: ${{ convertToJson(variables) }}
Expand Down
6 changes: 6 additions & 0 deletions .pipelines/platform-connectivity-hub-azfw-policy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ stages:
steps:
- checkout: self

- template: templates/steps/load-variables.yml

- template: templates/steps/show-variables.yml
parameters:
json: ${{ convertToJson(variables) }}

- template: templates/steps/deploy-platform-connectivity-hub-azfw-policy.yml
parameters:
description: 'Deploy Azure Firewall Policy'
Expand Down
2 changes: 2 additions & 0 deletions .pipelines/platform-connectivity-hub-azfw.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ stages:

- template: templates/steps/load-log-analytics-vars.yml

- template: templates/steps/load-variables.yml

- template: templates/steps/show-variables.yml
parameters:
json: ${{ convertToJson(variables) }}
Expand Down
2 changes: 2 additions & 0 deletions .pipelines/platform-connectivity-hub-nva.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ stages:

- template: templates/steps/load-log-analytics-vars.yml

- template: templates/steps/load-variables.yml

- template: templates/steps/show-variables.yml
parameters:
json: ${{ convertToJson(variables) }}
Expand Down
2 changes: 2 additions & 0 deletions .pipelines/platform-logging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ stages:
steps:
- checkout: self

- template: templates/steps/load-variables.yml

- template: templates/steps/show-variables.yml
parameters:
json: ${{ convertToJson(variables) }}
Expand Down
4 changes: 4 additions & 0 deletions .pipelines/policy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ stages:

- template: templates/steps/load-log-analytics-vars.yml

- template: templates/steps/load-variables.yml

- template: templates/steps/show-variables.yml
parameters:
json: ${{ convertToJson(variables) }}
Expand Down Expand Up @@ -111,6 +113,8 @@ stages:

- template: templates/steps/load-log-analytics-vars.yml

- template: templates/steps/load-variables.yml

- template: templates/steps/show-variables.yml
parameters:
json: ${{ convertToJson(variables) }}
Expand Down
27 changes: 19 additions & 8 deletions .pipelines/roles.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,24 @@ stages:

jobs:

- job: CustomRolesJob
- deployment: CustomRolesJob
displayName: Custom Roles Job
environment: ${{ variables['Build.SourceBranchName'] }}
strategy:
runOnce:
deploy:
steps:
- checkout: self

steps:
- template: templates/steps/create-roles.yml
parameters:
description: 'Custom Role'
workingDir: $(System.DefaultWorkingDirectory)/roles
deployTemplates: [lz-netops, lz-secops, lz-subowner, lz-appowner, la-vminsights-readonly]
deployOperation: ${{ variables['deployOperation'] }}
- template: templates/steps/load-variables.yml

- template: templates/steps/show-variables.yml
parameters:
json: ${{ convertToJson(variables) }}

- template: templates/steps/create-roles.yml
parameters:
description: 'Custom Role'
workingDir: $(System.DefaultWorkingDirectory)/roles
deployTemplates: [lz-netops, lz-secops, lz-subowner, lz-appowner, la-vminsights-readonly]
deployOperation: ${{ variables['deployOperation'] }}
5 changes: 4 additions & 1 deletion .pipelines/templates/jobs/deploy-subscription.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ jobs:
steps:
- checkout: self

- template: ../steps/load-variables.yml

- template: ../steps/show-variables.yml
parameters:
json: ${{ convertToJson(variables) }}
Expand All @@ -48,7 +50,8 @@ jobs:
# Resolve partial configuration file specification
if [[ ! ${subscription} =~ .*/.* ]]; then
echo
echo "Resolving partial configuration file specifier: ${subscription} ..."
echo "Resolving partial configuration file specifier: ${subscription}"
echo "Finding matching configuration file(s) under path ${config}/${enviro}"
readarray -t lines < <(find ${config}/${enviro} -type f -name "*${subscription}*" | sed "s/^${config_sed}\///g")
if [[ ${#lines[@]} < 1 || ${#lines[@]} > 1 ]]; then
echo "##vso[task.logissue type=error]Found ${#lines[@]} subscription configuration file matches based on qualifier: ${subscription}. Partial configuration file name search must have exactly 1 match."
Expand Down
2 changes: 2 additions & 0 deletions .pipelines/templates/jobs/trigger-subscriptions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ jobs:

steps:

- template: ../steps/load-variables.yml

- template: ../steps/show-variables.yml
parameters:
json: ${{ convertToJson(variables) }}
Expand Down
49 changes: 48 additions & 1 deletion .pipelines/templates/steps/deploy-management-groups.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,55 @@ parameters:

steps:

# Modern step for deploying management group structure based on 'var-managementgroup-hierarchy' YAML variable
- task: AzureCLI@2
displayName: ${{ parameters.description }}
condition: ne(variables['var-managementgroup-hierarchy'], '')
displayName: ${{ parameters.description }} (modern)
inputs:
azureSubscription: $(serviceConnection)
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
$(var-bashPreInjectScript)
templateFile=structure-v2.bicep
echo "Deploying $templateFile using ${{ parameters.deployOperation }} operation"
hierarchyJson='$(var-managementgroup-hierarchy)'
declare -a groups=()
readarray -t groups < <(echo $hierarchyJson | jq -r 'recurse | [.id] + [.name] + ( .children?[] | [.id] + [.name] ) | @sh')
echo "Found ${#groups[@]} management groups to deploy in configuration file"
for group in "${groups[@]}"
do
declare -a "parts=($group)"
parentManagementGroupId=${parts[0]}
parentManagementGroupName=${parts[1]}
childManagementGroupId=${parts[2]}
childManagementGroupName=${parts[3]}
echo " Deploying new child management group [id=$childManagementGroupId, name=$childManagementGroupName] of parent management group [id=$parentManagementGroupId, name=$parentManagementGroupName]"
az deployment mg ${{ parameters.deployOperation }} \
--location $(deploymentRegion) \
--management-group-id $(var-parentManagementGroupId) \
--template-file $templateFile \
--parameters \
topLevelManagementGroupName='$(var-topLevelManagementGroupName)' \
parentManagementGroupId="$parentManagementGroupId" \
childManagementGroupId="$childManagementGroupId" \
childManagementGroupName="$childManagementGroupName"
done
$(var-bashPostInjectScript)
workingDirectory: '${{ parameters.workingDir }}'

# Legacy step for deploying management group structure hard-coded in management-groups/structure.bicep
- task: AzureCLI@2
condition: eq(variables['var-managementgroup-hierarchy'], '')
displayName: ${{ parameters.description }} (legacy)
inputs:
azureSubscription: $(serviceConnection)
scriptType: 'bash'
Expand Down
45 changes: 45 additions & 0 deletions .pipelines/templates/steps/load-variables.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# ----------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.
#
# THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
# EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
# ----------------------------------------------------------------------------------

steps:

# Load Variables
- task: Bash@3
displayName: Load Variables
inputs:
targetType: inline
script: |
$(var-bashPreInjectScript)
### -------------------------------------------------------------------------------------------------
### Create the 'var-parentManagementGroupId' and 'var-topLevelManagementGroupName'
### variables (used in YAML pipeilne definitions) based on information extracted from the
### newer 'var-managementgroup-hierarchy' variable, if it is defined.
### -------------------------------------------------------------------------------------------------
hierarchyJson='$(var-managementgroup-hierarchy)'
if [[ -n $hierarchyJson ]]; then
echo "The new 'var-managementgroup-hierarchy' variable IS defined."
echo "REMAPPING 'var-parentManagementGroupId' and 'var-topLevelManagementGroupName' variables."
parentManagementGroupId=`echo $hierarchyJson | jq -r '.id'`
topLevelManagementGroupName=`echo $hierarchyJson | jq -r '.children[0].id'`
echo "##vso[task.setvariable variable=var-parentManagementGroupId]$parentManagementGroupId"
echo "##vso[task.setvariable variable=var-topLevelManagementGroupName]$topLevelManagementGroupName"
else
echo "The new 'var-managementgroup-hierarchy' variable IS NOT defined."
echo "USING existing 'var-parentManagementGroupId' and 'var-topLevelManagementGroupName' variables."
fi
### -------------------------------------------------------------------------------------------------
### Add more scripts here to remap other variables. For example, if you refactor for existing (flat)
### variables to represent them in JSON notation (objects), then this is a useful approach to
### maintaining backward compatibility while supporting a newer and improved configuration schema.
### -------------------------------------------------------------------------------------------------
$(var-bashPostInjectScript)
51 changes: 35 additions & 16 deletions .pipelines/templates/steps/show-variables.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,41 +14,60 @@ parameters:

steps:

# Show variables (hard-coded)
# Show variables
- task: Bash@3
displayName: Variables
displayName: Show Variables
inputs:
targetType: inline
script: |
$(var-bashPreInjectScript)
echo
echo
echo "COMMON"
echo
echo " deploymentRegion = $(deploymentRegion)"
echo " serviceConnection = $(serviceConnection)"
echo " vmImage = $(vmImage)"
echo " deployOperation = $(deployOperation)"
echo " subscriptionsPathFromRoot = $(subscriptionsPathFromRoot)"
echo " var-TriggerSubscriptionDeployOn = $(var-TriggerSubscriptionDeployOn)"
# echo " var-bashPreInjectScript = $(var-bashPreInjectScript)"
# echo " var-bashPostInjectScript = $(var-bashPostInjectScript)"
echo
echo
echo "MANAGEMENT GROUPS (modern)"
echo
echo " var-managementgroup-hierarchy = $(var-managementgroup-hierarchy)"
echo
echo "MANAGEMENT GROUPS"
echo
echo "MANAGEMENT GROUPS (legacy)"
echo
echo " var-parentManagementGroupId = $(var-parentManagementGroupId)"
echo " var-topLevelManagementGroupName = $(var-topLevelManagementGroupName)"
echo
echo
echo "LOGGING"
echo " var-logging-managementGroupId = $(var-logging-managementGroupId)"
echo " var-logging-subscriptionId = $(var-logging-subscriptionId)"
echo " var-logging-logAnalyticsResourceGroupName = $(var-logging-logAnalyticsResourceGroupName)"
echo " var-logging-logAnalyticsWorkspaceName = $(var-logging-logAnalyticsWorkspaceName)"
echo
echo "HUB NETWORKING"
echo " var-hubnetwork-managementGroupId = $(var-hubnetwork-managementGroupId)"
echo " var-hubnetwork-subscriptionId = $(var-hubnetwork-subscriptionId)"
echo
printenv | grep -i "^var-logging-"
echo
echo
echo "HUB NETWORKING (core)"
echo
printenv | grep -i -P '^var-hubnetwork-(?!nva|azfw)'
echo
echo
echo "HUB NETWORKING WITH AZURE FIREWALL"
echo
printenv | grep -i '^var-hubnetwork-azfw-'
echo
echo
echo "HUB NETWORKING WITH NETWORK VIRTUAL APPLIANCE"
echo
printenv | grep -i '^var-hubnetwork-nva-'
$(var-bashPostInjectScript)
40 changes: 38 additions & 2 deletions config/variables/CanadaESLZ-main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,45 @@
# currently executing pipeline.

variables:

# Management Groups
var-parentManagementGroupId: 343ddfdb-bef5-46d9-99cf-ed67d5948783
var-topLevelManagementGroupName: pubsec
# var-parentManagementGroupId: 343ddfdb-bef5-46d9-99cf-ed67d5948783
# var-topLevelManagementGroupName: pubsec

# Management Groups (modern)
var-managementgroup-hierarchy: >
{
"name": "Tenant Root Group",
"id": "343ddfdb-bef5-46d9-99cf-ed67d5948783",
"children": [
{
"name": "Azure Landing Zones for Canadian Public Sector",
"id": "pubsec",
"children": [
{
"name": "Platform", "id": "pubsecPlatform",
"children": [
{ "name": "Identity", "id": "pubsecPlatformIdentity", "children": [] },
{ "name": "Connectivity", "id": "pubsecPlatformConnectivity", "children": [] },
{ "name": "Management", "id": "pubsecPlatformManagement", "children": [] }
]
},
{
"name": "LandingZones", "id": "pubsecLandingZones",
"children": [
{ "name": "DevTest", "id": "pubsecLandingZonesDevTest", "children": [] },
{ "name": "QA", "id": "pubsecLandingZonesQA", "children": [] },
{ "name": "Prod", "id": "pubsecLandingZonesProd", "children": [] }
]
},
{
"name": "Sandbox", "id": "pubsecSandbox",
"children": []
}
]
}
]
}
# Logging
var-logging-managementGroupId: pubsecPlatformManagement
Expand Down
Loading

0 comments on commit c62dcfc

Please sign in to comment.