14th March 2018

Gone are the times of Microsoft and Linux living in parallel universes, nowadays with the introduction of Cloud Services and Containers, the matter of choosing an OS is meaningless. While practicing DevOps, you will find out that the technologies and tools used are not the most important part, we should be instead focusing on fast delivery and quality in a full-fledged agile environment.

Today’s recipe is about how to add quality gates to our CI builds using tools such as SonarQube, leveraging on the Microsoft Azure Container Instances.

Recipe: CI Builds with SQ and Azure Containers

- 1 SonarQube Server
- 1 Azure Container Registry
- 1 Azure Container Instance
- 1 VSTS CI Build Pipeline
- 1 Ubuntu host OS
- 1 Azure CLI for Linux

Cooking time: 6 minutes


1) Creating the SonarQube server

The quickest way to create a SonarQube server instance is to deploy it from a Docker pre-baked image, like the ones you can find in DockerHub or, like in our recipe, Azure Container Registry.

The tool I have chosen to deploy a download image from the ACR and create the container as an Azure Container Instance is the Azure CLI, which works on several OS platforms. For this example, we are going to install the Azure CLI for Ubuntu.

Installing Azure CLI for Ubuntu:

Step 1: Copy and paste this into your Linux shell

AZ_REPO=$(lsb_release -cs)
echo "deb [arch=amd64] https://packages.microsoft.com/repos/azure-cli/ $AZ_REPO main" | \
sudo tee /etc/apt/sources.list.d/azure-cli.list
sudo apt-key adv --keyserver packages.microsoft.com --recv-keys 52E16F86FEE04B979B07E28DB02C46DF417A0893
sudo apt-get install apt-transport-https
sudo apt-get update && sudo apt-get install azure-cli

Now that we have the Azure CLI installed, let’s proceed with the container into Azure Container Instances, for that we need first to create the Azure resource group in the location we are going to host the Docker Container Instance.

Step 2: Create Azure Resource Group

az group create --name myResourceGroup1 --location westeurope

The output should be something like:

 "id": "/subscriptions/xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx/resourceGroups/myResourceGroup1",
 "location": "westeurope",
 "managedBy": null,
 "name": "myResourceGroup1",
 "properties": {
 "provisioningState": "Succeeded"
 "tags": null

Then, create the container, providing the name of the image in the container registry, the port to open and the public DNS name for the container.

Step 3: Create the SonarQube container in the Azure Container Instances

az container create --resource-group myResourceGroup1 --name sqcontainer --image sonarqube --dns-name-label sqmagentysdemo --ports 9000

The output should be something like:

 "additionalProperties": {},
 "containers": [
 "additionalProperties": {},
 "command": null,
 "environmentVariables": [],
 "image": "sonarqube",
 "instanceView": null,
 "name": "sqcontainer",
 "ports": [
 "additionalProperties": {},
 "port": 9000,
 "protocol": null
 "resources": {
 "additionalProperties": {},
 "limits": null,
 "requests": {
 "additionalProperties": {},
 "cpu": 1.0,
 "memoryInGb": 1.5
 "volumeMounts": null
 "id": "/subscriptions/xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx/resourceGroups/myResourceGroup1/providers/Microsoft.ContainerInstance/containerGroups/sonarqubecontainer",
 "imageRegistryCredentials": null,
 "instanceView": {
 "additionalProperties": {},
 "events": [],
 "state": "Pending"
 "ipAddress": {
 "additionalProperties": {},
 "dnsNameLabel": "sqmagentysdemo",
 "fqdn": "sqmagentysdemo.westeurope.azurecontainer.io",
 "ip": "",
 "ports": [
 "additionalProperties": {},
 "port": 9000,
 "protocol": "TCP"
 "location": "westeurope",
 "name": "sqcontainer",
 "osType": "Linux",
 "provisioningState": "Creating",
 "resourceGroup": "myResourceGroup1",
 "restartPolicy": "Always",
 "tags": null,
 "type": "Microsoft.ContainerInstance/containerGroups",
 "volumes": null

Step 4: Check if the container is up.

az container show --resource-group myResourceGroup1 --name sqcontainer

We also can check it in the Azure portal:

Screenshot from 2018-02-24 12-49-54

2) Integrate the SQ Container Instance as part of your  CI pipeline

Now that we have SonarQube up and running on Azure, it’s time to use it in our Builds. For this example, I’m using one of my Build Definitions in VSTS (similarly this works for Jenkins, TeamCity, Bamboo, and others) to include 2 steps, one for starting the SonarQube analysis and another one to generate the summary report.

You can find the SonarQube plugin here: https://marketplace.visualstudio.com/items?itemName=SonarSource.sonarqube#overview

All you need to provide for these plugins is the URL and port of the SonarQube server and the Token generated when you finish the first time configuration.

You can see how the integration works in VSTS with our container:


And how the results are displayed in SonarQube


If you want to check the logs of the SonarQube server you can access them from the Azure CLI:

az container logs --resource-group myResourceGroup1 --name sqcontainer

Deleting your SQ container

If you don’t want to leave your container living forever, you can delete your container as easy as:

az container delete --resource-group myResourceGroup1 --name sonarqubecontainer


Other possible recipes:

  • Create your own Docker Container Images with SonarQube and deploy it into ACI using the Azure CLI.
  • Create the Docker Container Images from the bash or PowerShell as part of your Build steps, deploy it into ACI, use it in your pipeline and then destroy it after.


I found this solution particularly simple, as it avoids having to set up your own SQ server from scratch. SQ is not going to run 24/7, you can take the container up and down anytime, you don’t need a server for it. Additionally, the virtual machine where it is running the SQ server can be used for multiple purposes, containers will help us to draw these isolation boundaries between this and other containers, having a better utilisation of the VM resources.

Integrating with your CI pipelines can be done easily through the plugins available in the market, either for VSTS/TFS, Bamboo, Jenkins, etc. In case you want to do your own plugin, its as easy as using the REST APIs that SQ is offering to use its quality gates even from your scripts.

Azure CLI allows you to do quick and easy operations into Azure besides you use Windows, MacOs or Linux. No need to go fancy with PowerShell or another scripting tool.

I hope you find your perfect recipe!

Happy baking!


About Eduardo Ortega
Principal Engineer - Head of DevOps at MagenTys MCSE, MCSD, MCDBA, MCAD, MCSP, MCSTS, PSD, PSM, CSD, Splunk PU