使用Ansible Tower构建VM,我希望只有在定义了其他磁盘的变量时,才能够创建其他磁盘

使用Ansible Tower构建VM,我希望只有在定义了其他磁盘的变量时,才能够创建其他磁盘,ansible,ansible-tower,ansible-awx,Ansible,Ansible Tower,Ansible Awx,我目前正在跨AWS和VSphere构建Ansible image playbook模板,我希望能够定义多个额外的磁盘,但只有当它们通过变量定义时 剧本: --- - hosts: localhost connection: local gather_facts: False tasks: - name: Launch Windows 2016 VM Instance vmware_guest: validate_certs: no datace

我目前正在跨AWS和VSphere构建Ansible image playbook模板,我希望能够定义多个额外的磁盘,但只有当它们通过变量定义时

剧本:

---
- hosts: localhost
  connection: local
  gather_facts: False

  tasks:

  - name: Launch Windows 2016 VM Instance
    vmware_guest:
      validate_certs: no
      datacenter: "{{ vm_datacenter }}"
      folder: "{{ vm_folder }}"
      name: "{{ vm_servername }}"
      state: poweredon
      template: "{{ vm_template }}"
      cluster: "{{ vm_cluster }}"
      disk:
       - size_gb: "{{ vm_disk_size0 | default(80) }}"
         type: "{{ vm_disk_type0 | default(thin) }}"
         datastore: "{{ vm_disk_datastore0 }}"
       - size_gb: "{{ vm_disk_size1 }}"
         type: "{{ vm_disk_type1 }}"
         datastore: "{{ vm_disk_datastore1 }}"
       - size_gb: "{{ vm_disk_size2 }}"
         type: "{{ vm_disk_type2 }}"
         datastore: "{{ vm_disk_datastore2 }}"
       - size_gb: "{{ vm_disk_size3 }}"
         type: "{{ vm_disk_type3 }}"
         datastore: "{{ vm_disk_datastore3 }}"
      hardware:
        memory_mb: "{{ vm_memory_mb | default(8192) }}"
        num_cpus: "{{ vm_num_cpus | default(4) }}"
      networks:
      - name: "{{ vm_network }}"
        start_connected: yes
        vlan: "{{ vm_network }}"
        device_type: vmxnet3
        type: dhcp
        domain: "{{ vm_domain }}"
      customization:
        hostname: "{{ vm_servername }}"
        orgname: Redacted
        password: "{{ winlocal_admin_pass }}"
        timezone: 255
      wait_for_ip_address: yes 
    register: vm  
变量:

vm_disk_datastore0: C6200_T2_FCP_3Days
vm_disk_size0: 80
vm_disk_type0: thin
vm_disk_datastore1: "C6200_T2_FCP_3Days"
vm_disk_size1: "50"
vm_disk_type1: "thin"
vm_disk_datastore2: "C6200_T2_FCP_3Days"
vm_disk_size2: "20"
vm_disk_type2: "thin"
vm_disk_datastore3: ""
vm_disk_size3: ""
vm_disk_type3: ""
错误:

{
    "_ansible_parsed": false,
    "exception": "Traceback (most recent call last):\n  File \"/var/lib/awx/.ansible/tmp/ansible-tmp-1568948672.23-135785453591577/AnsiballZ_vmware_guest.py\", line 113, in <module>\n    _ansiballz_main()\n  File \"/var/lib/awx/.ansible/tmp/ansible-tmp-1568948672.23-135785453591577/AnsiballZ_vmware_guest.py\", line 105, in _ansiballz_main\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n  File \"/var/lib/awx/.ansible/tmp/ansible-tmp-1568948672.23-135785453591577/AnsiballZ_vmware_guest.py\", line 48, in invoke_module\n    imp.load_module('__main__', mod, module, MOD_DESC)\n  File \"/tmp/ansible_vmware_guest_payload_6vidiw/__main__.py\", line 2396, in <module>\n  File \"/tmp/ansible_vmware_guest_payload_6vidiw/__main__.py\", line 2385, in main\n  File \"/tmp/ansible_vmware_guest_payload_6vidiw/__main__.py\", line 2008, in deploy_vm\n  File \"/tmp/ansible_vmware_guest_payload_6vidiw/__main__.py\", line 1690, in configure_disks\n  File \"/tmp/ansible_vmware_guest_payload_6vidiw/__main__.py\", line 1608, in get_configured_disk_size\nValueError: invalid literal for int() with base 10: ''\n",
    "_ansible_no_log": false,
    "module_stderr": "Traceback (most recent call last):\n  File \"/var/lib/awx/.ansible/tmp/ansible-tmp-1568948672.23-135785453591577/AnsiballZ_vmware_guest.py\", line 113, in <module>\n    _ansiballz_main()\n  File \"/var/lib/awx/.ansible/tmp/ansible-tmp-1568948672.23-135785453591577/AnsiballZ_vmware_guest.py\", line 105, in _ansiballz_main\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n  File \"/var/lib/awx/.ansible/tmp/ansible-tmp-1568948672.23-135785453591577/AnsiballZ_vmware_guest.py\", line 48, in invoke_module\n    imp.load_module('__main__', mod, module, MOD_DESC)\n  File \"/tmp/ansible_vmware_guest_payload_6vidiw/__main__.py\", line 2396, in <module>\n  File \"/tmp/ansible_vmware_guest_payload_6vidiw/__main__.py\", line 2385, in main\n  File \"/tmp/ansible_vmware_guest_payload_6vidiw/__main__.py\", line 2008, in deploy_vm\n  File \"/tmp/ansible_vmware_guest_payload_6vidiw/__main__.py\", line 1690, in configure_disks\n  File \"/tmp/ansible_vmware_guest_payload_6vidiw/__main__.py\", line 1608, in get_configured_disk_size\nValueError: invalid literal for int() with base 10: ''\n",
    "changed": false,
    "module_stdout": "",
    "rc": 1,
    "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error"
}
剧本:

---
- hosts: localhost
  connection: local
  gather_facts: False

  tasks:

  - name: Launch Windows 2016 VM Instance - No additional Disk
    vmware_guest:
      validate_certs: no
      datacenter: "{{ vm_datacenter }}"
      folder: "{{ vm_folder }}"
      name: "{{ vm_servername }}"
      state: poweredon
      template: "{{ vm_template }}"
      cluster: "{{ vm_cluster }}"
      disk:
      - size_gb: "{{ vm_disk_size0 }}"
        type: "{{ vm_disk_type0 }}"
        datastore: "{{ vm_disk_datastore0 }}"
      hardware:
        memory_mb: "{{ vm_memory_mb | default(8192) }}"
        num_cpus: "{{ vm_num_cpus }}"
      networks:
      - name: "{{ vm_network }}"
        start_connected: yes
        vlan: "{{ vm_network }}"
        device_type: vmxnet3
        type: dhcp
        domain: "{{ vm_domain }}"
      customization:
        hostname: "{{ vm_servername }}"
        orgname: redacted
        password: "{{ winlocal_admin_pass }}"
        timezone: 255
      wait_for_ip_address: yes 
    register: vm
    when: num_disks == 0

  - name: Launch Windows 2016 VM Instance 1 Additional Disk
    vmware_guest:
      validate_certs: no
      datacenter: "{{ vm_datacenter }}"
      folder: "{{ vm_folder }}"
      name: "{{ vm_servername }}"
      state: poweredon
      template: "{{ vm_template }}"
      cluster: "{{ vm_cluster }}"
      disk:
      - size_gb: "{{ vm_disk_size0 }}"
        type: "{{ vm_disk_type0 }}"
        datastore: "{{ vm_disk_datastore0 }}"
      - size_gb: "{{ vm_disk_size1 }}"
        type: "{{ vm_disk_type1 }}"
        datastore: "{{ vm_disk_datastore1 }}"
      hardware:
        memory_mb: "{{ vm_memory_mb | default(8192) }}"
        num_cpus: "{{ vm_num_cpus }}"
      networks:
      - name: "{{ vm_network }}"
        start_connected: yes
        vlan: "{{ vm_network }}"
        device_type: vmxnet3
        type: dhcp
        domain: "{{ vm_domain }}"
      customization:
        hostname: "{{ vm_servername }}"
        orgname: redacted
        password: "{{ winlocal_admin_pass }}"
        timezone: 255
      wait_for_ip_address: yes 
    register: vm
    when: num_disks == 1

  - name: Launch Windows 2016 VM Instance 2 Additional Disks
    vmware_guest:
      validate_certs: no
      datacenter: "{{ vm_datacenter }}"
      folder: "{{ vm_folder }}"
      name: "{{ vm_servername }}"
      state: poweredon
      template: "{{ vm_template }}"
      cluster: "{{ vm_cluster }}"
      disk:
      - size_gb: "{{ vm_disk_size0 }}"
        type: "{{ vm_disk_type0 }}"
        datastore: "{{ vm_disk_datastore0 }}"
      - size_gb: "{{ vm_disk_size1 }}"
        type: "{{ vm_disk_type1 }}"
        datastore: "{{ vm_disk_datastore1 }}"
      - size_gb: "{{ vm_disk_size2 }}"
        type: "{{ vm_disk_type2 }}"
        datastore: "{{ vm_disk_datastore2 }}"
      hardware:
        memory_mb: "{{ vm_memory_mb | default(8192) }}"
        num_cpus: "{{ vm_num_cpus }}"
      networks:
      - name: "{{ vm_network }}"
        start_connected: yes
        vlan: "{{ vm_network }}"
        device_type: vmxnet3
        type: dhcp
        domain: "{{ vm_domain }}"
      customization:
        hostname: "{{ vm_servername }}"
        orgname: redacted
        password: "{{ winlocal_admin_pass }}"
        timezone: 255
      wait_for_ip_address: yes 
    register: vm
    when: num_disks == 2


etc

看起来您应该使用1个磁盘构建虚拟机,您可以确定,当您运行播放时,该磁盘将始终存在,您可以将其作为此列表中的第一个变量:

vms:
  0:
    vm_disk_datastore: "C6200_T2_FCP_3Days"
    vm_disk_size: "80"
    vm_disk_type: "thin"
  1:
    vm_disk_datastore: "C6200_T2_FCP_3Days"
    vm_disk_size: "50"
    vm_disk_type: "thin"
  2:
    vm_disk_datastore: "C6200_T2_FCP_3Days"
    vm_disk_size: "20"
    vm_disk_type: "thin"
  3:
    vm_disk_datastore: ""
    vm_disk_size: ""
    vm_disk_type: ""
因为我不知道有什么方法可以循环子模块参数以使它们存在或不存在,所以用一个您确信会存在的磁盘构建您的vm。为了保持一致性,上面提到的哪一个应该是您列表中的第一个。或者,您需要重新构建逻辑以深入列表,查找可以使用诸如selectattr和map之类的jinja过滤器输入的特定值

- name: Launch Windows 2016 VM Instance
    vmware_guest:
      validate_certs: no
      datacenter: "{{ vm_datacenter }}"
      folder: "{{ vm_folder }}"
      name: "{{ vm_servername }}"
      state: poweredon
      template: "{{ vm_template }}"
      cluster: "{{ vm_cluster }}"
      disk:
       - size_gb: "{{ vms.0.vm_disk_size }}"
         type: "{{ vms.0.vm_disk_type }}"
         datastore: "{{ vms.0.vm_disk_datastore }}"
      hardware:
        memory_mb: "{{ vm_memory_mb | default(8192) }}"
        num_cpus: "{{ vm_num_cpus | default(4) }}"
      networks:
      - name: "{{ vm_network }}"
        start_connected: yes
        vlan: "{{ vm_network }}"
        device_type: vmxnet3
        type: dhcp
        domain: "{{ vm_domain }}"
      customization:
        hostname: "{{ vm_servername }}"
        orgname: Redacted
        password: "{{ winlocal_admin_pass }}"
        timezone: 255
      wait_for_ip_address: yes 
    register: vm 
构建后,使用这个不同的模块深入研究添加额外的磁盘

- name: Add disks to virtual machine
  vmware_guest_disk:
    hostname: "{{ vm_servername }}"
    datacenter: "{{ vm_datacenter }}"
    disk:
      - size_gb: "{{ item.vm_disk_size }}"
        type: "{{ item.vm_disk_type }}"
        datastore: "{{ item.vm_disk_datastore }}"
        state: present
    loop: "{{ vms }}"
    loop_control:
      label: "Disk {{ my_idx}} - {{ item.vm_disk_datastore }}"
      index_var: my_idx
    when:
      - item.vm_disk_datastore != ""
      - item.vm_disk_size != ""
      - item.vm_disk_type != ""
      - my_idx > 0
这将通过一个循环将该变量从您决定定义它的地方拉入,然后通过口述记录列表循环使用正确的标签拉取值,但只有当它们有值时才这样做(如果在该列表中留空是您计划执行的操作,如果没有,甚至不需要when)。这还允许您向上扩展,只需在列表中添加更多项,而无需扩展任务。如果由于无法依赖列表顺序而需要编辑第一个任务,但需要输入一个变量,则需要确保对第二个任务中的磁盘进行了更改,并忽略使用第一个任务中添加的磁盘


此外,此模块上的文档说明,使用此模块调用的现有磁盘将被调整为该大小,并且不能使用该模块进行缩减,因此,如果要避免这种情况,请进行一些数据检查,以将配置的磁盘大小与变量中的磁盘大小进行比较,这样,如果要缩减磁盘大小,则可以跳过该任务(或者,如果您只是不想更改现有vm)。

非常感谢您提供的信息。我尝试了您的方法,它按照您的预期填充了磁盘信息,但磁盘并未实际创建:看起来vm_来宾模块试图用磁盘1覆盖初始磁盘0:“msg”:“给定的磁盘大小小于找到的磁盘大小(52428800<83886080)。不允许减少磁盘。",因此基本上您的方法是按预期工作的,但是对于dict中的每个附加磁盘,vm_来宾模块都会认为它是主磁盘,并会尝试覆盖,而不是添加附加磁盘。哦,好的,我认为,由于它通过该循环向整个vmware_来宾模块提供数据,因此它会从该列表中获取数据并尝试分配给该磁盘vm仅在循环的迭代中使用磁盘。让我用另一个选项编辑上面的答案。这是循环列表的一个非常好的示例。我也开始研究vm_来宾_磁盘模块,但它在2.8中是新的,最新的塔版本是2.7.9:)。当我们升级时,我会回来参考这段代码,它非常简洁。同时,我刚刚默认通过一个disk_number变量调用模块的多次迭代,非常感谢您的帮助,ebrewer,这是我第一次真正使用stackoverflow,您帮了我很大的忙。非常感谢。
- name: Add disks to virtual machine
  vmware_guest_disk:
    hostname: "{{ vm_servername }}"
    datacenter: "{{ vm_datacenter }}"
    disk:
      - size_gb: "{{ item.vm_disk_size }}"
        type: "{{ item.vm_disk_type }}"
        datastore: "{{ item.vm_disk_datastore }}"
        state: present
    loop: "{{ vms }}"
    loop_control:
      label: "Disk {{ my_idx}} - {{ item.vm_disk_datastore }}"
      index_var: my_idx
    when:
      - item.vm_disk_datastore != ""
      - item.vm_disk_size != ""
      - item.vm_disk_type != ""
      - my_idx > 0