Deploying Infrastructure on Azure with Ansible
By , - Source: Toms IT Pro

If you must do something more than once, you should automate it. Otherwise, your human failings will cause an issue at some point. It is not a matter of if this happens, but when. IaaS is not an exception. Deploying infrastructure on any cloud platform means that we should have our environments managed through code.

Ansible – Open Source Goodness

I am a big fan of open source tools and Ansible is no exception here. Not long ago Ansible got acquired by Redhat, but stayed open source and free. It is developed in Python on Github and is currently available in version 2.3.

MORE: Microsoft Azure vs. Amazon Web Services: Cloud Comparison

The architecture is as simple as it gets, because Ansible's master server can run on any platform, except for Windows (although I heard rumours of people getting it to work in Windows Subsystem for Linux, WSL).

From there Ansible can execute commands against both Linux (via ssh) and Windows (via WinRM). That said, a decision to use Ansible means a decision to use Linux, usually CentOS or Redhat.

A quick way to getting started is pulling down this Docker image that I created. This image comes with Ansible, the azure cli, aws cli and PowerShell for Linux installed. You can now enter this Docker image, provided you have Docker running on your machine, by executing from a command line
docker run -it davidobrien1985/centos_ansible_powershell bash

You will now find yourself inside of a new Docker container at your bash prompt.

Execute "ansible --version" to verify the version of Ansible you are running and that Ansible is indeed installed.

Setting Azure up for Ansible

Ansible executes against Azure in two ways; Username and Password or a Service Principal.
I prefer the latter and this is how you set it up. If you have followed the "Packer on Azure" article, then this will look familiar:


param (
[string]$app_password = 'P@ssw0rd',
[string]$subscription_ID = ''


$azuresub = Get-AzureRmSubscription -SubscriptionId $subscription_ID

New-AzureRmADApplication -DisplayName ansible -HomePage -IdentifierUris -Password $app_password -Verbose

$app = Get-AzureRmADApplication -IdentifierUri -Verbose

New-AzureRmADServicePrincipal -ApplicationId $app.ApplicationId -Verbose
Start-Sleep -Seconds 20
$roleassignment = New-AzureRmRoleAssignment -ServicePrincipalName -RoleDefinitionName Owner -Scope "/subscriptions/$subscription_ID" -Verbose

$result = @{SubscriptionID="$($azuresub.Id)"; TenantID = "$($azuresub.TenantId)"; ClientID = "$($app.ApplicationId)"; client_secret = $app_password;}


Execute this PowerShell script to create a Service Principal in Azure Active Directory that we will use from Ansible to execute authenticated actions against Azure.

The output will be the input to our Ansible execution script ( We will set the values to environment variables, which Ansible will pick up. Ideally Ansible would be running from a CI server such as Visual Studio Team Services (VSTS) or Jenkins, which would set the environment variables for us so that we do not have to set them in our code, but for a development / demo environment this will do.

Executing Ansible

Copy the following two files to a directory on your computer.

The first is "" and will be used to make it easier for us to actually execute Ansible, instead from calling it from the command line we will wrap it into a script. Enter the information from the above PowerShell script. (Make sure to NOT store your secrets in plain-text anywhere. Check out "Ansible Vault" for a way to encrypt your secrets for Ansible.)

export AZURE_TENANT=""
export AZURE_SECRET="P@ssw0rd"

ansible-playbook -i localhost, ansible/playbook.yaml -vvvv

The second is our Ansible playbook called "playbook.yaml". This example uses one of the quickstart templates that Microsoft Azure provides on Github to deploy a simple, single Windows VM. This ARM template requires a few parameters that I pass in via the "parameters" array.
- name: Deploy Azure ARM template.
  hosts: localhost
  connection: local
  gather_facts: false
    - name: Create Azure Deploy
        state: present
        resource_group_name: tomsitpro
        template_link: ''
            value: "adobrien"
            value: "P@ssw0rd123!"
            value: "tomsitprodns"

Ansible works almost completely with YAML files (, which is very easy to understand. However, they are very particular about whitespace and indentation, so make sure that you have your IDE set up properly to highlight issues with YAML syntax.

Now execute the following command from your command line:

docker run -i -v {path to your local directory}:/ansible -t davidobrien/centos_ansible_powershell bash ansible/

and watch Ansible do its thing.

Ansible Modules for Azure

There are 18 modules available for Azure, and you should absolutely be using the one I demonstrated above. Ansible should not be a way to work around ARM templates, but rather a way to deploy your ARM templates.

Ansible uses a very powerful templating engine called Jinja2, which will enable you to easily generate very generic JSON Azure ARM templates that are portable, repeatable and easy to understand.

Alternatively, you can also use the other available modules which leverage the python SDK for Azure RM, but will only deploy resources sequentially and not in parallel, plus they are not maintained by Microsoft, like the ARM template platform, which means that they might not support the latest features.

The "azure_rm_deployment" module for Ansible already supports all resource types available on Azure, like Function Apps, Logic Apps, CosmosDB etc.

For more in-depth knowledge of Ansible on Azure check out their documentation page.