Azure Blueprints as Code & Github Actions

Amine Charot
6 min readSep 25, 2019

Most of companies cope the management of their infrastructure. They should manage the ARM Templates Deployment, the Policy Definitions and the RBACs.
The problem is that when we treat these three aspects separately, we increase the risk of being wrong. If one day a company decides to create a new subscription or recreate one, they should think about the ARM Templates, the Policy Definitions and RBACs separately,how to put them together, should we apply a policy before running an ARM Template Deployment ...

In order to make the orchestration of the deployment easier, we need a solution to define a pattern for Azure Subscriptions. We also need a solution that unifies the management of ARM Template, Policy Definitions and RBACs instead of managing them separately.

Azure Blueprints is not a new kind of ARM Templates. You will keep the same thing that you used to use to deploy and govern your infrastracture but you will add a new orchestration layer which will help you avoid this kind of conversation since you will be able to unify everything and everything you will have to manage is the Azure Blueprints !

This will help to avoid this kind of conversation since you will be able to unify all the aspects. you just have to manage the Azure Blueprints !

Azure Blueprints has a lifecycle since it is an Azure Resource:

  • Creation & publishing a blueprint definition;
  • Creation & publishing a new version;
  • Removing a version or the whole blueprint.

Azure Blueprints definition is composed of Templates, policies and roles that you’ve designed. So when you deploy it, you will deploy all the templates, policies and roles which will ensure the same governance across all your Azure subscriptions.

Azure Blueprints is composed of Artifacts which are the resources that Azure Blueprints will deploy. What I like the most about this component is the hierarchy :

It is to much organized and we know exactly what we are going to deploy ! In this case we will create or update a dedicated Resource Group for API Management. Then, we will deploy an API Management instance (we don’t need to change anything in our APIM template to adapt to Blueprints which is a cool thing).

Another important component of Azure BluePrints is static Parameters, they are defined at Blueprints definition level :

If you are sure that your Resource Group will be deployed in a Region, you may uncheck “this value should be specified when the blueprint is assigned”, so you can select a static parameter.

You may need your own static parameter, no problem ! You can use REST API to create an Azure Blueprints using your own parameters ! You can use dynamic parameters. They are provided when the Blueprint is assigned. Using the dynamic parameters, you will benefit of the reusibility of your definitions since the values can be configured.

I invite you to watch Alex Frankel’s video on Azure Friday which gives an overview about Azure Blueprints : Youtube.

Blueprints As Code + Github Actions

We shouldn’t forget about automation. Sure, Azure Blueprints is a great service which provides us more organization. But we won’t be able to put it inside a CI/CD pipeline if we use the Portal.

Azure makes that possible using Blueprints as code. Its documentation is clear which makes understanding the concept easy to perceive.

Documentation : https://github.com/Azure/azure-blueprints

I see some important commands that makes the automation possible :

Import-AzBlueprintWithArtifact : It import the definition of the blueprint
Get-AzBlueprint : Get a Blueprint
Publish-AzBlueprint : Publish a Blueprint
New-AzBlueprintAssignment : Assign a Blueprint

In Build phase, I will import the blueprint definition with artifacts, then I will publish it.

In deploy phase, I will assign the latest published blueprint to a subscription.

  • How does it work ?

The Import-AzBlueprintWithArtifact will look in the input path that we gave. It looks for the Blueprint.json.

/i\ Make sure that you have a title case because in the code of the command they have :

const string blueprintFileName = "Blueprint";            
var blueprintPath = GetValidatedFilePath(inputPath, blueprintFileName);

Blueprint.json defines a blueprint without any artifacts. It contains the parameters that will be used and the resource group. It looks like :

Then, the same command will import the artifacts inside the Blueprint. Make sure that you have a folder named “Artifacts” in the same input path.

/i\ Make sure that you have a title case because in the code of the command they have :

const string artifacts = "Artifacts";             
var artifactsPath = GetValidatedFolderPath(inputPath, artifacts);

Inside Artifacts, we can add our artifacts of one of the three kinds :

  • template;
  • roleAssignment;
  • policyAssignment.

After running the command we must see

The Publish-AzBlueprint will publish a version of blueprint that we get using Get-AzBlueprint

In the deploy phase, we will assign the blueprint to a subscription. Like the publish, we will need the latest published blueprint.

In the script, using the command New-AzBlueprintAssignment, you must give a path of a json that defines the blueprint which we will publish, the value of the parameters … It looks like :

Note : In order to automate, I modify the blueprintId using the deployment script using :

(Get-Content $assignmentFile).replace("{{BLUEPRINTID}}",$createdBlueprint.id) | Set-Content $assignmentFile
  • Putting all together using Github Actions

Github Actions is finally on preview for public repositories. Thanks to the articles of Wilfried Woivre and the articles of Michael Fery, I was able to work with Github Actions without any problem (well with some few problems :D). The articles are in French but since they are well written, you can translate them without any problems.

Wilfried Woivre Blog : https://blog.woivre.fr/

Michael Fery Blog : http://mfery.com/

Firas Mdimagh Blog : https://firas.site/

Github Actions is a workflow automation platform defined using a YAML File which allows us to create a custom CI/CD Pipeline.

The YAML File describes all what I’ve talked about. The env part defines the variables that I’ve used inside my scripts.

env:        
SUBSCRIPTIONID: fa971420-4388-457a-ac56-1cd453785f14 BLUEPRINTPATH: ./infrastructure
BLUEPRINTNAME: testBluePrint
SPNID: 529a5a8d-4dc4-4f1a-9d4f-3ba5f130446f
SPNPASS: ${{ secrets.spnPass }}
TENANTID: eb73c9bc-7f90-4841-9556-c3a56cc82c79
MGID: charotmg

For the secrets such as the SPN Pass, can be saved in the secrets tab inside Github :

You can access to it using ${{ secrets.SECRETNAME }}.

Two jobs are declared : Build and Deploy.

In the Build job I run three steps which are the checkout and the scripts to import and publish the blueprint.

The import script : Click Here

The publish script : Click Here

In the Deploy one, I run two steps to checkout and assign the latest published blueprint.

The assignment script : Click Here

This repository contains all the scripts used in the article (and a lot of useless commits) : https://github.com/charotAmine/BlueprintsAsCode

Bella ciao,

--

--