Ansible Azure Resource Manager — VMs and Resources
Introduction
VMs and Resources. Automate Azure infrastructure with Ansible using the azure.azcollection collection. This guide covers authentication, resource creation, management, and cleanup with practical playbook examples.
Prerequisites
# Install the Azure collection
ansible-galaxy collection install azure.azcollection
# Install Python dependencies
pip install boto3 botocore # AWS
# pip install azure-identity azure-mgmt-compute # Azure
# pip install google-auth google-cloud-compute # GCP
Authentication
# Method 1: Environment variables (recommended for CI/CD)
# export AWS_ACCESS_KEY_ID=your-key
# export AWS_SECRET_ACCESS_KEY=your-secret
# Method 2: Ansible variables (use Vault for secrets)
---
- name: Azure automation
hosts: localhost
connection: local
vars:
region: us-east-1
environment:
AWS_REGION: "{{ region }}"
Create Resources
---
- name: Provision Azure infrastructure
hosts: localhost
connection: local
gather_facts: false
vars:
project_name: myapp
environment: production
region: us-east-1
tasks:
- name: Create Azure resources
ansible.builtin.debug:
msg: "Provisioning {{ project_name }} in {{ environment }}"
- name: Tag all resources
ansible.builtin.set_fact:
common_tags:
Project: "{{ project_name }}"
Environment: "{{ environment }}"
ManagedBy: ansible
Manage Resources
- name: List existing resources
ansible.builtin.debug:
msg: "Managing Azure resources for {{ project_name }}"
- name: Ensure security groups exist
ansible.builtin.debug:
msg: "Security group configuration for {{ environment }}"
Resource Lifecycle
- name: Update resources
ansible.builtin.debug:
msg: "Updating {{ project_name }} resources"
tags: update
- name: Delete resources (use with caution)
ansible.builtin.debug:
msg: "Destroying {{ project_name }} resources"
tags: [destroy, never]
Variables Structure
# group_vars/azure/main.yml
azure_region: us-east-1
azure_instance_type: t3.medium
azure_image: ami-0123456789abcdef0
# group_vars/azure/vault.yml (encrypted)
azure_access_key: !vault |
$ANSIBLE_VAULT;1.2;AES256
...
Dynamic Inventory
# inventory/azure.yml
plugin: azure.azcollection.aws_ec2
regions:
- us-east-1
- eu-west-1
filters:
tag:ManagedBy: ansible
keyed_groups:
- key: tags.Environment
prefix: env
- key: instance_type
prefix: type
compose:
ansible_host: public_ip_address
Error Handling
- name: Provision with retry
block:
- name: Create resource
ansible.builtin.debug:
msg: "Creating Azure resource"
register: resource_result
retries: 3
delay: 10
until: resource_result is not failed
rescue:
- name: Cleanup on failure
ansible.builtin.debug:
msg: "Rolling back Azure changes"
always:
- name: Log result
ansible.builtin.debug:
msg: "Provisioning complete"
CI/CD Integration
# .github/workflows/deploy-azure.yml
name: Deploy to Azure
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install dependencies
run: |
pip install ansible azure-azcollection
ansible-galaxy collection install azure.azcollection
- name: Run playbook
run: ansible-playbook deploy.yml
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_KEY }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET }}
Cost Management
- name: Check for unused resources
ansible.builtin.debug:
msg: "Audit Azure resources for cost optimization"
tags: audit
- name: Schedule resource shutdown (dev environments)
ansible.builtin.debug:
msg: "Shutting down dev resources for cost savings"
when: environment == "development"
tags: cost_savings
Troubleshooting
| Issue | Solution |
|---|---|
| Authentication failed | Check environment variables or vault credentials |
| Region not found | Verify region name matches Azure naming |
| Rate limit exceeded | Add retries and delay to tasks |
| Resource already exists | Use state: present for idempotent operations |
| Timeout on creation | Increase wait_timeout parameter |
Best Practices
- Use dynamic inventory — auto-discover resources instead of static lists
- Tag everything — consistent tags enable filtering and cost tracking
- Encrypt credentials with Ansible Vault — never commit plaintext keys
- Use check mode for dry runs:
--check --diff - Implement state management — track what Ansible created for cleanup
- Separate environments — different inventories for dev/staging/production
Conclusion
Ansible with the azure.azcollection collection provides infrastructure-as-code for Azure. Combine dynamic inventory, encrypted credentials, and CI/CD pipelines for fully automated cloud management. Start with the examples above and expand based on your infrastructure needs.