PoC/Lighthouse project at a potential new prospector. This is to create Landing Zone within Azure. The Landing Zone will consist of:
- Key Vault
- vNet
- NSG
- Log Analytics
- Storage Account
More information on Azure Landing zone can be found here
Building the Landing Zone was using Azure Blueprints. You can find great examples of Azure Blueprints here
The CI/CD tooling of choice is Azure DevOps. The pipeline is constructed as pipeline as a code, which can be located within azure-pipeline.yaml
file
To run the pipeline within your sandbox Azure DevOps & Azure Tenant create new project within Azure DevOps. Link the github repository to the project once done create new service connection to your Azure tenant.
In order to create Management Groups with the service connection, add the service connection SPN within the Access Control at the default Tenant Root Group level. Add the SPN as a Owner.
To create the resources via the blueprint user-assigned identity object was created. The user-assigned object was then given permission at Management Group root level as a Blueprint Operator role & Contributor role. The Contributor role is to ensure the user-assigned object has permissions to create resources within the subscription.
Below is the command to create user assigned object:
az identity create --name $NAME --resource-group $RESOURCE_GROUP_NAME --subscription $SUBSCRIPTIONID
Add the newly created user-assigned object to the Blueprint Operator
role by running below az command.
az role assignment create --assignee USER_ASSIGNED_OBJECT_ID --role "Blueprint Operator"
To run the pipeline the variables below are the values that will need changing within the azure-pipeline.yaml
:
- serviceConnection
- blueprintName
- mgmtGroupName
- KVAccessPolicy
- SubId
- UserIdentity
Before running the management group step change the value of the subscriptionID within .\mgmtGroup\management.json
If you've never used Blueprints before, this can be little overwhelming. You can build your first blueprint with the UI to understand how everything works. You can try it at aka.ms/getblueprints and learn more about it in the docs or watch this 15 minute overview.
Download the Az.Blueprint module from the powershell gallary:
Install-Module -Name Az.Blueprint
To push blueprint definition to Azure
Import-AzBlueprintWithArtifact -Name LandingZone -ManagementGroupId "DevMG" -InputPath ".\landingZone\blueprint"
Publish a new version of that definition so it can be assigned:
# Get the blueprint we just created
$bp = Get-AzBlueprint -Name Boilerplate -ManagementGroupId "DevMG"
# Publish version 1.0
Publish-AzBlueprint -Blueprint $bp -Version 1.0
Assign the blueprint to a subscription
# Get the version of the blueprint you want to assign, which we will pas to New-AzBlueprintAssignment
$publishedBp = Get-AzBlueprint -ManagementGroupId "DevMG" -Name "LandingZone" -LatestPublished
# Each resource group artifact in the blueprint will need a hashtable for the actual RG name and location
$rgHash = @{ name="MyBoilerplateRG"; location = "eastus" }
# all other (non-rg) parameters are listed in a single hashtable, with a key/value pair for each parameter
$parameters = @{ principalIds="caeebed6-cfa8-45ff-9d8a-03dba4ef9a7d" }
# All of the resource group artifact hashtables are themselves grouped into a parent hashtable
# the 'key' for each item in the table should match the RG placeholder name in the blueprint
$rgArray = @{ SingleRG = $rgHash }
# Assign the new blueprint to the specified subscription (Assignment updates should use Set-AzBlueprintAssignment
New-AzBlueprintAssignment -Name "UniqueBlueprintAssignmentName" -Blueprint $publishedBp -Location eastus -SubscriptionId "00000000-1111-0000-1111-000000000000" -ResourceGroupParameter $rgArray -Parameter $parameters
A blueprint consists of the main blueprint json file and a series of artifact json files. The blueprint folder structure will be like the following:
Blueprint directory
* blueprint.json
* artifacts
- artifact.json
- ...
- more-artifacts.json
The blueprint folder can be found landingZone\blueprints
. Running the pipeline will execute .\scripts\blueprint.ps1
The script is taking two parameters which are stored as hash table. The KV-AccessPolicy
is the object ID of the SPN that assigns itself access once the Key Vault is created. The SubscriptionId
is part of the resourceId when adding diagnostic settings to each of the resources.
As part of the repository having there is example of implementing Management Groups within Azure. The powershell script is located within .\scripts\mgmtGroup.ps1
The script will look for json file located within .\mgmtGroup\management.json
{
"MgmtGroup": {
"GroupName": [
{
"name": "RootLevel"
},
{
"name": "Management",
"parent": "RootLevel",
"subscriptionId": "xxxxx-xxxx-xxx-xxx-xxxxx"
}
]
}
}
Each child consists details of the management group to be created the above examples shows management groups called:
- RootLevel
- Management
The RootLevel is implemented underneath tenant level subsequent groups are then managed under the root level. The management group is child of the RootLevel management group. Below image illustrates design of the Management Group level
The above image RootLevel is "Root Management Group"
Part of the repository you will find ARM Template building out resources such as:
- Key Vault
- AKS Cluster
- ACR (Container Registry)
To interact with Azure APIs, AKS cluster requires service principal. A service principal is needed to dynamically create and managed other resources.
Part of the infrastructure build service principal is created for the AKS cluster. The application id and the secret is then stored in the keyvault created to store the credentials. Once the container registry is created the container registry is then attached to the AKS cluster.
Idea would be to have the pipeline to create SPN accounts in order to assign to resources such as AKS cluster. To create SPN account as a SPN you need to add permissions to your service connection account. Permission required to create service principal accounts using service principal are:
- The Service Principal requires Owner permission to the subscription
- API access: Windows Azure Active Directory: "Manage apps that this app creates or owns"
- Microsoft Graph "Read and write directory data", "Access directory as the signed in user"
The above permission can be found on the Supported legacy APIs Azure Active Directory Graph
More information on creating service principal with existing service principal can be found here.
Example of the working pipeline can be found on extra-azure-pipeline.yaml