If you’ve ever had to spin up the same resources on Azure multiple times, you know how repetitive that gets. It’s the same cycle every time: virtual machines, network interfaces, and resource groups.
But what if you didn’t have to repeat yourself?
Ansible is already popular for automating server setups, configurations, and deployments. But it also works neatly with Azure. So instead of clicking through the Azure Portal or writing long PowerShell scripts, you can write and run a short YAML playbook, and Ansible takes care of the rest.
In this article, you’ll learn how to use Ansible to automate resource creation on Azure. You’ll see how to apply it to real-world examples, such as creating a resource group and a virtual machine.
Prerequisites
Before we start, let’s make sure you’ve got the basics in place. To follow along and get the most out of this guide, you need to:
- Have Ansible installed on your local machine or control node
- Set up API access to Azure using a service principal or Azure CLI login
- Install the Azure Ansible Collection (
azure.azcollection
) usingansible-galaxy
. To quickly do this, run the command: ansible-galaxy collection install azure.azcollection
- Ensure you’ve got Python packages like
azure-mgmt-resource
,azure-identity
andazure-cli-core
installed. You can do all of this by running:pip install --upgrade azure-cli-core azure-identity azure-mgmt-resource
- Configure your
ansible.cfg
to point to the proper inventory file or plugin - Have access to an active Azure subscription
Ansible is used in Azure to automate provisioning, configuration management, and application deployment across Azure resources. It enables consistent and repeatable infrastructure operations using declarative YAML-based playbooks.
In Azure environments, Ansible can:
- Deploy virtual machines, networking, and storage via the Azure Resource Manager (ARM) or Terraform
- Configure VMs post-deployment with required packages, settings, or security hardening
- Manage hybrid environments, combining on-premises and Azure infrastructure
- Integrate with Azure DevOps or CI/CD pipelines for automated workflows
Ansible’s agentless architecture makes it suitable for managing Azure Linux and Windows VMs without needing extra software on target machines.
Let’s walk through a few examples to show how Ansible fits in.
A simple use case: Creating a resource group
Start small. Just spin up a resource group in a specific region. You could do it in the Azure UI or CLI, but here’s how it looks with Ansible:
- name: Create Azure resource group
hosts: localhost
tasks:
- name: Create resource group
azure_rm_resourcegroup:
name: myResourceGroup
location: eastus
That’s it: one playbook, one task. You can commit it to version control, rerun it, and even share it across your team.
A medium use case: Provisioning a virtual machine
Now, suppose you want to create a virtual machine, a public IP address, and a virtual network. With Ansible, you describe all of that in one place with no back and forth in the UI. Here’s a snippet:
- name: Provision VM in Azure
hosts: localhost
tasks:
- name: Create virtual machine
azure_rm_virtualmachine:
resource_group: myResourceGroup
name: myVM
admin_username: azureuser
admin_password: P@ssword1234
image:
offer: UbuntuServer
publisher: Canonical
sku: '18.04-LTS'
version: latest
vm_size: Standard_B1s
This ensures a consistent VM every time you run it, with the same size, image, and region.
An advanced use case: Full app deployment pipeline
Let’s say you’re rolling out a typical three-tier app. You’ve got a load balancer up front, a backend VM handling business logic, and a managed database sitting behind them. You want to deploy the whole setup in one go, with all parts connected securely.
Ansible enables you to orchestrate the entire workflow. You can split the logic into roles, include secrets through Ansible Vault, and run everything from a CI/CD pipeline. With one push, your infrastructure is live on Azure.
Pros and cons of using Ansible with Azure
These trade-offs make Ansible a strong option for configuration management and procedural automation, though tools like Terraform may be better suited for declarative infrastructure provisioning.
Pros | Description |
Idempotent automation | You can run the same playbook multiple times without breaking your setup (as long as each run completes successfully). |
Readable YAML syntax | Easy to understand and edit, even for beginners |
No agents needed | Ansible uses SSH or APIs. No need to install daemons or agents on your VMs. |
Scales well | Works effectively for both small setups and large, multi-cloud architectures |
Built-in Azure modules | Many tasks are already covered for you, from networking to compute to identity. |
Cons | Description |
Slower at scale | Compared to tools like Terraform, Ansible can appear slower when managing a large number of resources. |
State tracking is external | It doesn’t keep track of state like Terraform; you need to rely on tags or external tools to track what’s deployed. |
Requires setup | You’ll need to set up credentials, service principals, and permissions before you can run any commands. |
Ansible’s strength lies in its ability to abstract complexity behind clean YAML definitions. With Azure, that power is unlocked through the azure.azcollection
. This is a maintained set of modules that lets you manage everything from virtual machines to load balancers, Key Vaults, databases, and more.
Each module in this collection maps directly to a specific Azure service or API, and they’re designed to be idempotent.
That means you can run the same playbook multiple times, and your infrastructure won’t be duplicated or broken. But it also means understanding which modules to use, and when, makes a huge difference in building stable, predictable automation.
Let’s walk through the core groups of Azure modules in Ansible, from the foundational to the advanced.
1. Resource management modules
Before deploying a VM or database, you need a resource group or a base deployment template.
azure_rm_resourcegroup
: Creates, updates, or deletes resource groupsazure_rm_resource
: Lets you interact with any Azure resource directly if a specific module doesn’t existazure_rm_deployment
: Deploys ARM templates, which is especially useful if you’re transitioning from declarative JSON templates to Ansible playbooks
Practical example: Teams often start by using these modules to manage dev environments, spinning up and tearing down sandboxes during CI/CD test runs.
2. Compute modules
Provisioning compute resources is one of the most common use cases. These modules let you spin up VMs, scale sets, or apply VM extensions post-deployment.
azure_rm_virtualmachine
: Create Linux or Windows VMs from the marketplace or custom imagesazure_rm_virtualmachinescaleset
: Launch horizontally scalable compute instancesazure_rm_virtualmachineextension
: Add features like monitoring agents, configuration scripts, or anti-virus tools
Practical example: You’re rolling out a fleet of worker nodes for a data processing job. You want the VM creation, software installation, and log shipping agent to all be part of one Ansible run. This is where these modules shine.
3. Networking modules
Networking in Azure can be elaborate. You’ve got NICs, virtual networks, public IPs, subnets, and load balancers, all of which need to interact seamlessly.
azure_rm_networkinterface
azure_rm_virtualnetwork
azure_rm_subnet
azure_rm_publicipaddress
azure_rm_loadbalancer
Practical example: You want to deploy a three-tier architecture. With these modules, you can define isolated networks for your frontend, backend, and database tiers. With Ansible’s networking modules, you can define isolated subnets for each tier, assign IP ranges, and control access using network security groups and routing rules.
This allows you to keep your database hidden from the internet while still enabling the frontend to serve traffic and connect securely to the backend.
4. Identity & security modules
If you’re managing secrets or enforcing identity policy, you should use Azure Key Vault and RBAC-related modules.
azure_rm_keyvault
azure_rm_keyvaultsecret
azure_rm_roleassignment
Practical example: You store sensitive credentials like database passwords or API keys in Azure Key Vault. With these modules, you can inject secrets during deployment without exposing them in your codebase.
5. Data services modules
Ansible can also provision managed database services. This is great for stateful app deployment.
azure_rm_sqldatabase
azure_rm_mysqlserver
azure_rm_postgresqlserver
Practical example: Automate the creation of a PostgreSQL instance, configure its firewall, and link it to a virtual machine (VM) in the same playbook. This reduces manual provisioning errors and makes deployments reproducible.
So, you’ve seen why Ansible is a great fit for automating Azure workloads. You’ve also had a peek at some of the Azure modules available in Ansible. Now, it’s time to put all of that into practice.
Let’s walk through the whole process, step by step.
1. Installing and configuring Ansible for Azure
Before writing your first playbook, you need to install the necessary tools and set up the required credentials.
a. Install Ansible
You can install Ansible using pip. This method gives you the most flexibility.
python3 -m pip install --user "ansible[azure]"
You can also use your system’s package manager, then add Azure support using pip. The assumption here is that you spun up a Debian-based Linux machine.
sudo apt update
sudo apt install ansible python3-pip
python3 -m pip install --user "ansible[azure]"
b. Install the Azure collection
The azure.azcollection
contains all the Azure-specific modules you’ll be using.
ansible-galaxy collection install azure.azcollection --force
c. Set up Azure credentials
Ansible authenticates with Azure using a service principal. To create one, run:
az ad sp create-for-rbac --name ansible-sp --role Contributor \
--scopes /subscriptions/YOUR_SUBSCRIPTION_ID
Take note of the appId
, password
, tenant
, and subscription
.
Now, configure your credentials using one of two methods:
- Environment variables:
export AZURE_SUBSCRIPTION_ID="your-subscription-id"
export AZURE_CLIENT_ID="your-app-id"
export AZURE_SECRET="your-password"
export AZURE_TENANT="your-tenant-id"
- Credentials file at
~/.azure/credentials
[default]
subscription_id=your-subscription-id
client_id=your-app-id
secret=your-password
tenant=your-tenant-id
This setup enables Ansible to connect to Azure securely using your service principal.
2. Writing a multi-resource Ansible playbook for Azure
Next, you’ll write a playbook that does the following:
- Creates a resource group
- Provisions a virtual machine
- Sets up an Azure Key Vault
- Adds a secret to the vault
Save this playbook as azure-setup.yml
:
---
- hosts: localhost
connection: local
collections:
- azure.azcollection
vars:
rg: demo-rg
location: eastus
vm_name: demoVM
kv_name: demoKeyVault
tasks:
- name: Create resource group
azure_rm_resourcegroup:
name: "{{ rg }}"
location: "{{ location }}"
- name: Deploy Ubuntu VM
azure_rm_virtualmachine:
resource_group: "{{ rg }}"
name: "{{ vm_name }}"
admin_username: azureuser
image:
publisher: Canonical
offer: UbuntuServer
sku: '22_04-lts'
version: latest
vm_size: Standard_B1s
- name: Create Key Vault
azure_rm_keyvault:
resource_group: "{{ rg }}"
name: "{{ kv_name }}"
tenant_id: "{{ lookup('env','AZURE_TENANT') }}"
sku: standard
- name: Add secret to Key Vault
azure_rm_keyvaultsecret:
vault_uri: "https://{{ kv_name }}.vault.azure.net/"
secret_name: "MySecret"
secret_value: "S3cureV@lue"
This playbook utilizes variables for flexibility and runs locally, as it interacts directly with Azure’s APIs.
3. Running the playbook and verifying the deployment
To run the playbook:
ansible-playbook azure-setup.yml
If all goes well, you’ll see output confirming each task was successful.
Verify your resources
From the Azure CLI:
az group show -n demo-rg
az vm show -g demo-rg -n demoVM
az keyvault secret show --vault-name demoKeyVault --name MySecret
From the Azure Portal:
Open the portal, navigate to “Resource groups,” and select “demo-rg
.” You’ll see the VM, Key Vault, and other related resources.
4. Cleaning up the environment
Once you’ve finished testing, you can remove everything to avoid incurring charges.
Create a cleanup playbook called cleanup.yml
:
---
- hosts: localhost
connection: local
collections:
- azure.azcollection
tasks:
- name: Delete resource group
azure_rm_resourcegroup:
name: demo-rg
state: absent
Run it like this:
ansible-playbook cleanup.yml
That deletes the resource group and everything inside it, including VMs, Key Vaults, public IPs, and more.
5. Extra layer: Use dynamic inventory for ongoing configuration
Once your VM is up, you might want to run additional Ansible playbooks on it. To do that:
- Enable SSH access on the VM
- Add it to your Ansible inventory
- Use Ansible’s dynamic Azure inventory plugin to fetch VM details automatically
This connects the dots between infrastructure provisioning and server configuration.
When working with Azure and Ansible, consider adopting the following best practices:
Best practice | Why it’s essential |
Externalise config & secrets | Prevents environment drift |
Dynamic inventory & tagging | Keeps hosts organized and current |
Module-first strategy | Ensures repeatable, idempotent runs |
Secret management via vaults | Protects credentials from exposure |
Scale with concurrency & callbacks | Handles large deployments efficiently |
Transactional playbooks | Promotes clean project states |
Drift detection | Maintains long-term infrastructure integrity |
1. Externalize environment configuration
Keep VM sizes, disk types, network tiers and other Azure parameters outside your playbooks. Use external vars (group_vars
, host_vars
) or pull values dynamically (via CLI or CMDB).
Hard‑coding values limits playbook reuse and leads to errors when deploying across environments. Avoiding fixed values helps teams adopt a consistent playbook for multiple environments without needing to edit it each time. Adopting this practice early saves confusion later.
2. Centralize inventory with dynamic groups
Use Azure’s dynamic inventory plugin to discover hosts automatically. Leverage tags and conditional generators to split VMs into groups (env=prod
, role=web
). Static inventory files quickly become outdated.
Tag-based grouping gives you dynamic control and makes the playbook easily auditable. Enable dynamic grouping based on real-time Azure metadata. That prevents manual drift and keeps your automation robust.
3. Hide secrets using Key Vault & Ansible Vault
Do not store secrets in playbooks. Instead, store credentials in Azure Key Vault (or Ansible Vault for local dev) and retrieve them at runtime. Committed secrets risk exposure. Tools like GitGuardian flag repositories for leaked tokens, which is a top vulnerability. Use platform-level identity tools to avoid secret sprawl.
4. Lean on Azure modules and avoid CLI calls
Always use azure_rm_*
modules instead of az
CLI within your playbooks. This is because modules are idempotent, structured, and integrate cleanly with error handling and Ansible logic. CLI commands are brittle and harder to debug. Modules manage checks and retries more effectively than free-form shell tasks.
5. Implement transactional playbooks with rollback logic
Chain-related tasks (e.g., resource group → VMs → secrets). Add a final verification step, and if that fails, trigger rollback or cleanup. Partial deployments leave the infrastructure in an inconsistent state. Without rollback, teams waste time debugging.
Every playbook should either complete successfully or revert to its original state. Even simple clean-up playbooks can serve as manual rollback tools when automation fails.
6. Monitor idempotency & detect configuration drift
Run your playbooks repeatedly in dev or QA and note any “changed” tasks. Any drift could mean broken logic. Use checks like Azure Policy or checksum comparisons to detect external changes.
Infrastructure often changes outside Ansible; teams manually update settings, run scripts, or use the cloud console. That breaks idempotency. CI pipelines should run drift detection playbooks before any modification is made, and then fail the deployment if unwanted changes are found.
Bonus tips
- Tag everything early: Apply tags like
env
,owner
,project
to every resource. Many teams regret starting without tags. - Use Blue/Green naming patterns: For infrastructure updates, provision new stacks under a name like
app-v2
, validate, then switch DNS or load balancer. Then tear downapp-v1
. This avoids downtime. - Guard against resource quotas: Pre-flight checks for vCPU and subnet limits can catch issues before deployment. Azure quotas are a common pitfall.
When people hear you’re automating Azure, the first question that often comes up is: Why not just use Azure DevOps? Isn’t that what it’s for? Ansible is typically integrated into Azure DevOps pipelines when configuration automation is needed within a broader release process.
What is Azure DevOps?
Azure DevOps is a suite of Microsoft tools designed to manage the entire software development lifecycle. It makes it easier to manage source control, build and release pipelines, test management, and work tracking. The platform includes services like:
- Azure Repos for version control
- Azure Pipelines for continuous integration and delivery
- Azure Boards for project and task tracking
- Azure Artifacts for managing package dependencies
- Azure Test Plans for manual and exploratory testing
It’s a powerful ecosystem, especially if your team is already deep into the Microsoft stack. With Azure DevOps, you can go from code commit to deployment using a tightly integrated pipeline.
However, although Azure DevOps is great at managing software delivery, it might not be the best tool for provisioning and orchestrating infrastructure.
Azure DevOps architecture
Similarities between Ansible and Azure DevOps
Ansible and Azure DevOps share key capabilities in infrastructure automation and deployment orchestration, particularly in the context of modern DevOps workflows.
- Infrastructure as Code (IaC): Both automate IaC tasks. Azure DevOps is available through ARM or Terraform, and Ansible is available via YAML playbooks.
- CI/CD integration: Both can integrate into deployment pipelines and trigger actions based on code changes.
There’s definitely overlap, but the differences are where choice matters.
Key differences between Ansible and Azure DevOps
The table below summarizes the differences:
When to choose which tool
Ansible is often favored for its simplicity, agentless architecture, and true platform agnosticism. It enables fast, flexible automation across diverse environments without needing installed agents. Its open-source nature and vibrant community accelerate development through shared modules and rapid updates, especially for infrastructure orchestration like VM and network provisioning.
In contrast, Azure DevOps is tightly integrated with Microsoft tools and excels at managing the full software development lifecycle, including planning, building, testing, and deploying code.
Choose Azure DevOps for end-to-end app delivery within Microsoft ecosystems, and Ansible for fast, scalable infrastructure automation across heterogeneous systems.
Use Ansible and Azure DevOps together for maximum effect
You could use a more powerful pattern as well, such as:
- Using Azure DevOps pipelines to test and manage your Ansible code (using repos and CI).
- Running Ansible within those pipelines (via script tasks or Docker) to perform cloud infra provisioning or app configuration.
- Storing secrets with Key Vault and fetching them during Ansible runs.
This provides full traceability, from code check-in through infrastructure automation, while allowing Ansible to shine in its automation domain.
Illustration of the working relationship between Azure DevOps and Ansible in infrastructure automation
Spacelift adds structure and control to your Ansible workflows without getting in the way. It’s designed for teams using Infrastructure as Code and offers better visibility, policy enforcement, and Git-based workflows for your playbooks and roles.
With Spacelift, you can trigger Ansible runs from pull requests, test your changes automatically, and manage environment-specific variables from a GitOps workflow. You can also apply Open Policy Agent (OPA) policies to enforce compliance across teams and environments.
Everything runs through a centralized platform, with logs, approvals, and integrations with your existing CI/CD tools. It helps you move fast while keeping things secure, consistent, and audit-friendly.
Read this blog post to learn how to use a custom Spacelift dynamic inventory (tofusible) built specifically for OpenTofu and Ansible using the stack dependencies feature.
If you’re serious about scaling Ansible automation, Spacelift gives you the tools to do it right. Check our documentation, read our Ansible guide, or book a demo with one of our engineers.
Combining Ansible and Azure makes your automation more structured and efficient.
Instead of clicking through the Azure portal or tracking complex CLI commands, you can write clear YAML playbooks that define exactly what you want. Ansible takes care of the rest by talking directly to Azure behind the scenes.
This means your infrastructure builds itself consistently. You can deploy resource groups, virtual machines, networks, and secrets in a single run, without missing a step.
As your needs grow, so does your playbook. Whether you’re managing a small dev environment or rolling out a full-scale production setup, Ansible adapts. You make small changes, and the whole system reflects them predictably.
Manage Ansible better with Spacelift
Managing large-scale playbook execution is hard. Spacelift enables you to automate Ansible playbook execution with visibility and control over resources, and seamlessly link provisioning and configuration workflows.