如何基于现有Ansible Playbook在VMware中批量创建虚拟机?
批量创建VMware虚拟机的Ansible实现方案
当然可以实现批量创建!这正是Ansible自动化的核心优势之一。咱们只需要把待创建的虚拟机信息整理成结构化列表,然后通过Ansible的loop功能遍历这个列表,让整个任务流程为每台虚拟机重复执行一次就行。下面是具体的改造步骤,完全适配你现有的Playbook:
1. 改造变量文件:从单个VM变量转为VM列表
首先把你的variables.yml改成包含多台虚拟机信息的列表结构。比如我们可以定义一个vms_to_deploy的列表,每一个列表项就是一台虚拟机的完整配置:
# variables.yml vms_to_deploy: - vm_netmask: 255.255.252.0 vm_gateway: 10.100.8.1 vm_fqdn_name: mcdlnxevtp01.menarini.net vm_name: MCDLNXEVTP01 vm_folder: APP - EASYVISTA vm_cluster: MCDVMWCLU02 vm_resource_pool: 06 - PRD networks_name: dPG_3008_PRD disk_datastore: VMW_PRD_DS02 Vm_OS: Red Hat 7.6 vm_datacenter: MDC-METROPOOL vm_state: poweredoff vm_guest_id: rhel7_64Guest disk_size_gb: 50 disk_type: thin hardware_memory_mb: 8192 hardware_num_cpus: 4 hardware_scsi: paravirtual vm_validate_certs: no networks_device_type: vmxnet3 - vm_netmask: 255.255.252.0 vm_gateway: 10.100.8.1 vm_fqdn_name: mcdlnxevtp02.menarini.net vm_name: MCDLNXEVTP02 vm_folder: APP - EASYVISTA vm_cluster: MCDVMWCLU02 vm_resource_pool: 06 - PRD networks_name: dPG_3008_PRD disk_datastore: VMW_PRD_DS02 Vm_OS: Red Hat 7.6 vm_datacenter: MDC-METROPOOL vm_state: poweredoff vm_guest_id: rhel7_64Guest disk_size_gb: 60 disk_type: thin hardware_memory_mb: 16384 hardware_num_cpus: 8 hardware_scsi: paravirtual vm_validate_certs: no networks_device_type: vmxnet3
你可以根据实际需求添加更多虚拟机的配置项,每台机器的参数可以独立调整。
2. 修改Playbook:添加循环逻辑
接下来要修改你的Playbook,让所有任务遍历上面定义的虚拟机列表。最简洁的方式是把所有VM创建相关的任务放到一个block里,然后给这个block添加loop指令;当然你也可以给每个单独的任务添加loop,不过用block会更整洁。
修改后的Playbook如下:
- hosts: all gather_facts: false vars_files: - variables.yml connection: local tasks: - name: 批量创建虚拟机 block: - name: 生成安装配置文件 template: src: template_install.j2 dest: /root/cfg/{{ item.vm_name }}.cfg - name: 配置isolinux.cfg template: src: isolinux.j2 dest: /root/rhel/isolinux/isolinux.cfg # 注意:如果这个配置文件是全局共用的,不是每个VM单独的,就不要放在循环里! # 可以把这个任务移到block外面,只执行一次 - name: 复制配置文件到Satellite服务器 shell: scp /root/cfg/{{ item.vm_name }}.cfg root@10.100.64.50:/var/ftp/pub/kickstart/. - name: 生成安装ISO文件 shell: /root/makecdrom.sh {{ item.vm_name }} - name: 上传ISO到vSphere存储 vsphere_copy: host: <Myvcentername> login: <myvcenterusername> password: <Mycenterpassword> validate_certs: no src: /root/{{ item.vm_name }}.iso datacenter: {{ item.vm_datacenter }} datastore: VMW_LIBRARY01 path: ISO/{{ item.vm_name }}.iso - name: 创建虚拟机 vmware_guest: hostname: <Myvcentername> login: <myvcenterusername> password: <Mycenterpassword> datacenter: "{{ item.vm_datacenter }}" resource_pool: "{{ item.vm_resource_pool }}" validate_certs: no annotation: 'creata con script ansible ip address " {{ item.vm_ip_addr }} "' folder: "{{ item.vm_folder }}" name: "{{ item.vm_name }}" state: "{{ item.vm_state }}" guest_id: "{{ item.vm_guest_id }}" cluster: "{{ item.vm_cluster }}" cdrom: type: iso iso_path: "[VMW_LIBRARY01] ISO/{{ item.vm_name }}.iso" disk: - size_gb: "{{ item.disk_size_gb }}" type: "{{ item.disk_type }}" datastore: "{{ item.disk_datastore }}" hardware: memory_mb: "{{ item.hardware_memory_mb }}" num_cpus: "{{ item.hardware_num_cpus }}" scsi: paravirtual networks: - name: "{{ item.networks_name }}" device_type: vmxnet3 delegate_to: 127.0.0.1 register: deploy_vm loop: "{{ vms_to_deploy }}" loop_control: label: "{{ item.vm_name }}" # 让任务输出显示VM名称,更易读
关键修改点说明:
- 所有原来引用单个变量的地方(比如
{{ vm_name }})都改成了{{ item.vm_name }},因为现在每个迭代的变量都在item对象里 - 添加了
loop: "{{ vms_to_deploy }}",让整个block遍历虚拟机列表 - 新增
loop_control的label配置,这样Ansible执行时会显示当前处理的VM名称,而不是整个冗长的变量结构,方便排查问题 - 注意:如果你的
isolinux.cfg是所有VM共用的配置,不是每个VM单独生成的,记得把这个任务移到block外面,只执行一次,避免重复覆盖
3. 额外注意事项
- SCP免密登录:为了避免批量执行时每次输入Satellite服务器的密码,建议提前配置Ansible控制节点到Satellite的SSH密钥信任
- ISO文件清理:批量创建后,本地的ISO文件和配置文件可以添加一个清理任务,比如在block最后加一个
file模块删除这些临时文件 - 并发控制:如果需要同时创建多台VM,可以添加
serial: N(N是并发数)到play级别,控制同时执行的虚拟机数量,避免给vSphere造成过大压力 - 错误处理:可以添加
rescue块来处理单个VM创建失败的情况,比如清理该VM的临时文件,而不影响其他VM的创建
内容的提问来源于stack exchange,提问作者Simone Masi
相关产品推荐
相关产品推荐

