Azure Blueprint
Azure Blueprint - the easy way
At Ignite 2018 Microsoft presented Azure Blueprint for the first time. Azure Blueprint is a uniform way to deliver your ARM templates, Policies and Role Assignments to your Enterprise Subscriptions via CI/CD and source control.
Furthermore Azure Blueprint enables you to update security and other features on all deployments of the Blueprint, making it easy to maintain policies and security in a large Enterprise environment with many subscriptions in different environments.
To get started, you need to organize your subscriptions in Management Groups. That is easily done, if you follow the documentation provided here
Once your Root Management Group is set up, you are ready to start using Azure Blueprints.
Azure Blueprint by GUI
Of cource there is a nice GUI in the portal:
And of course you can create a new Blueprint in the portal:
And assign some artifacts to it:
Quickly add a resource group and a template - for a quick test this one will do just fine.
Give your Blueprint a version number and publish it:
But where is the fun in that? And, even more important, where is the CI/CD and source control in in this approach?
Azure Blueprint by Powershell
There are a few pre-requisites. You should have the latest version of AzureRM.Resources installed (I’m running version 6.5.0 at the moment), and you should have set up Management Groups with the proper access.
If we are to automate Azure Blueprint we have to be able to mainpulate the blueprints form the commandline. An easy way to get started with this is to use Powershell and the AxAzureBlueprint module.
If you are interested in the sourcecode for this project, it can be found here
The module can be installed form the Powershell Gallery, by running:
PS C:\>Import-Module AxAzureBlueprint
At the moment, the module contains the following cmdlets
PS C:\>Get-Command -Module AxAzureBlueprint
CommandType Name Version Source
----------- ---- ------- ------
Function Connect-AzureBlueprint 0.1.1 AxAzureBlueprint
Function Get-AzureBlueprint 0.1.1 AxAzureBlueprint
Function Get-AzureBlueprintArtifact 0.1.1 AxAzureBlueprint
Function Remove-AzureBlueprint 0.1.1 AxAzureBlueprint
Function Set-AzureBlueprint 0.1.1 AxAzureBlueprint
The cmdlets are pretty self-explanatory and if in doubt, you can always run help on them.
Before you can use the cmdlets in the module, you need to connect to your Azure Tenant. run this cmdlet:
PS C:\>Connect-AzureRMAccount
Create a new Blueprint
First off you need to connect to the Management Group you want to add your new Blueprint to. If you have an existing Management Group containing one or more subscriptions, you need the name of that Management Group. If you want to create a brand new Management Group for your Blueprint, just use the -Force switch when running the Connect-AzureBlueprint cmdlet.
Now you are ready to deploy your first Azure Blueprint from the commandline, but first you need to write the json-templates for the Blueprint.
You should start by creating a folder. The folder name will become the name of your Azure Blueprint.
Open your favorite json template editor. I prefer VS Code and I like to open my Blueprint folder, so I only see the Blueprint I am working on:
If you want to test how easy it is to create a new Azure Blueprint, just go ahead and add the code below to your Blueprint folder:
Run the following cmdlet:
Set-AzureBlueprint -BlueprintFolder C:\Dev\Vanilla
Now you can head over to your Azure Portal and find your Blueprint draft named Vanilla with one artifact called artifact:
And if you edit the Vanilla Draft, you will se, that the artifact has the json template you just published:
But what you can’t see in the GUI, is the additional information in the original json templates. This information, however, will be revealed, if you retrieve the templates with the apropriate cmdlets in Powershell:
PS C:\> Get-AzureBlueprint -Blueprint Vanilla
{
"properties": {
"parameters": {
"storageAccountType": {
"type": "string"
},
"tagName": {
"type": "string"
},
"tagValue": {
"type": "string"
},
"contributors": {
"type": "array"
},
"owners": {
"type": "array"
}
},
"resourceGroups": {
"storageRG": {
"name": "StorageAccount",
"location": "eastus2",
"dependsOn": []
}
},
"targetScope": "subscription",
"status": {
"timeCreated": "2018-11-10T07:14:36+00:00",
"lastModified": "2018-11-10T15:29:46+00:00"
}
},
"id": "/providers/Microsoft.Management/managementGroups/AutomatedSubscriptionMaintenance/providers/Microsoft.Blueprint/blueprints/Vanilla",
"type": "Microsoft.Blueprint/blueprints",
"name": "Vanilla"
}
PS C:\> Get-AzureBlueprintArtifact -Blueprint Vanilla -Artifact artifact
{
"properties": {
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"storageAccountTypeFromBP": {
"type": "string",
"defaultValue": "Standard_LRS",
"allowedValues": [
"Standard_LRS",
"Standard_GRS",
"Standard_ZRS",
"Premium_LRS"
],
"metadata": {
"description": "Storage Account type"
}
},
"tagNameFromBP": {
"type": "string",
"defaultValue": "NotSet",
"metadata": {
"description": "Tag name from blueprint"
}
},
"tagValueFromBP": {
"type": "string",
"defaultValue": "NotSet",
"metadata": {
"description": "Tag value from blueprint"
}
}
},
"variables": {
"storageAccountName": "[concat(uniquestring(resourceGroup().id), 'standardsa')]"
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"name": "[variables('storageAccountName')]",
"apiVersion": "2016-01-01",
"tags": {
"[parameters('tagNameFromBP')]": "[parameters('tagValueFromBP')]"
},
"location": "[resourceGroup().location]",
"sku": {
"name": "[parameters('storageAccountTypeFromBP')]"
},
"kind": "Storage",
"properties": {}
}
],
"outputs": {
"storageAccountSku": {
"type": "string",
"value": "[variables('storageAccountName')]"
}
}
},
"resourceGroup": "storageRG",
"parameters": {
"storageAccountTypeFromBP": {
"value": "[parameters('storageAccountType')]"
},
"tagNameFromBP": {
"value": "[parameters('tagName')]"
},
"tagValueFromBP": {
"value": "[parameters('tagValue')]"
}
},
"dependsOn": []
},
"kind": "template",
"id": "/providers/Microsoft.Management/managementGroups/AutomatedSubscriptionMaintenance/providers/Microsoft.Blueprint/blueprints/Vanilla/artifacts/artifact",
"type": "Microsoft.Blueprint/blueprints/artifacts",
"name": "artifact"
}
As you see the properties id, type and name are added to the template.
Conclusion
Creating and updating Azure Blueprints is incredibly easy. Once you have created a Blueprint, you just update it by changing the existing json templates or adding new artifacts and then setting the entire thing again.
With the AxBlueprintModule you do not need to update the template with the Azure added parameters. The module finds the existing Blueprint and Artifacts and updates them.
The hard part is writing proper templates, but more on that in the following blog post.