Azure Ubuntu 16.04环境下,Ansible Playbook能否用变量批量创建VM?
Yes, you absolutely can do this! Ansible’s loop capabilities make it straightforward to batch-create VMs using variables stored in an external file. Given your setup (Ubuntu 16.04, Ansible 2.4.3.0, Azure CLI 2.0.27), here’s a step-by-step implementation:
1. Create a Variables File for VM Details
First, create a YAML file (e.g., vm_configs.yml) that lists all 10 VMs with their respective names, passwords, and other required parameters. This keeps your playbook clean and makes it easy to update VM details later:
# vm_configs.yml target_vms: - vm_name: "prod-vm-01" admin_username: "azureadmin" admin_password: "StrongPass_2024!" resource_group: "my-production-rg" vm_size: "Standard_DS1_v2" nic_name: "prod-vm-01-nic" # Match your existing NIC naming convention - vm_name: "prod-vm-02" admin_username: "azureadmin" admin_password: "AnotherStrongPass_2024!" resource_group: "my-production-rg" vm_size: "Standard_DS1_v2" nic_name: "prod-vm-02-nic" # Add 8 more VM entries following the same structure
2. Write the Playbook with Loop Logic
Next, update your Ansible playbook to load this variables file and use with_items (compatible with Ansible 2.4) to iterate over each VM entry and create the resources:
# create_batch_vms.yml - name: Batch create Azure virtual machines hosts: localhost connection: local vars_files: - vm_configs.yml # Load our VM variables tasks: - name: Provision each VM azure_rm_virtualmachine: resource_group: "{{ item.resource_group }}" name: "{{ item.vm_name }}" vm_size: "{{ item.vm_size }}" admin_username: "{{ item.admin_username }}" admin_password: "{{ item.admin_password }}" network_interfaces: "{{ item.nic_name }}" os_type: Linux image: offer: UbuntuServer publisher: Canonical sku: 16.04-LTS version: latest with_items: "{{ target_vms }}" # Loop through each VM in our list register: vm_creation_output - name: Print creation status for each VM debug: msg: "Successfully created VM: {{ item.item.vm_name }} (ID: {{ item.id }})" with_items: "{{ vm_creation_output.results }}"
Key Notes:
- Loop Syntax: Since you’re on Ansible 2.4,
with_itemsis the correct loop construct (theloopkeyword was introduced in Ansible 2.5, butwith_itemsworks perfectly here). - Dependencies: Ensure you’ve already created the required network interfaces (NICs) for each VM, or extend the playbook to loop through NIC creation first using the same
target_vmslist. - Security Warning: Storing plain-text passwords in a YAML file is not secure. For production use, encrypt the variables file with Ansible Vault:
When running the playbook, useansible-vault encrypt vm_configs.yml--ask-vault-passto provide the vault password, or store it in a secure file with--vault-password-file.
Alternative: Use a CSV File
If you prefer managing VM details in a CSV (e.g., for easier editing in spreadsheets), you can use Ansible’s read_csv module to load the data:
Example CSV (vms_list.csv):
vm_name,admin_username,admin_password,resource_group,vm_size,nic_name prod-vm-01,azureadmin,StrongPass_2024!,my-production-rg,Standard_DS1_v2,prod-vm-01-nic prod-vm-02,azureadmin,AnotherStrongPass_2024!,my-production-rg,Standard_DS1_v2,prod-vm-02-nic
Updated Playbook Task:
- name: Load VM details from CSV read_csv: path: vms_list.csv key: vm_name register: vm_csv_data - name: Create VMs from CSV azure_rm_virtualmachine: resource_group: "{{ item.value.resource_group }}" name: "{{ item.value.vm_name }}" vm_size: "{{ item.value.vm_size }}" admin_username: "{{ item.value.admin_username }}" admin_password: "{{ item.value.admin_password }}" network_interfaces: "{{ item.value.nic_name }}" os_type: Linux image: offer: UbuntuServer publisher: Canonical sku: 16.04-LTS version: latest with_dict: "{{ vm_csv_data.dict }}"
This approach gives you flexibility in how you manage your VM inventory.
内容的提问来源于stack exchange,提问作者Bruce

