我想使用Ansible Tower构建VM,并且我希望能够仅在定义了变量后创建附加磁盘

时间:2019-09-20 02:54:51

标签: ansible ansible-tower ansible-awx

我目前正在跨AWS和VSphere构建Ansible图像剧本模板,我希望能够定义多个其他磁盘,但仅当通过变量定义它们时才可以。

剧本:

---
- 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"
}

这个想法是,如果在启动作业时未定义变量,则vm_guest模块将跳过该变量。

这是最好的方法吗?有谁能提出成功的前进道路?

更新:最好的方法可能是构建实例,然后使用vm_guest_disk通过以下建议的方法添加其他磁盘。 v2.8中提供了此模块。

我们的Tower版本是2.7.9,因此我将通过disk_num变量使用更详细的方法来进行多个vm_guest调用:

变量

num_disks: 0
vm_cluster: C6200_NPE_PC_ST
vm_datacenter: DC2
vm_disk_datastore0: C6200_T2_FCP_3Days
vm_disk_datastore1: ''
vm_disk_datastore2: ''
vm_disk_datastore3: ''
vm_disk_datastore4: ''
vm_disk_size0: 80
vm_disk_type0: thin
vm_disk_type1: ''
vm_disk_type2: ''
vm_disk_type3: ''
vm_disk_type4: ''
vm_domain: corp.local
vm_folder: /DC2/vm/ap-dev
vm_hostname: xyzvmserver.corp.local
vm_memory_mb: 16000
vm_network: C6200_10.110.64.0_24_VL1750
vm_num_cpus: 4
vm_servername: server05
vm_template: Windows2016_x64_AN_ESX_v1.1

剧本:

---
- 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

1 个答案:

答案 0 :(得分:0)

您似乎应该用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

这将通过循环从您决定定义的位置拉入该变量,然后循环遍历字典,以正确的标签拉取值,但只有在它们具有值的情况下才这样做(如果离开您计划在该列表中留空,如果不需要,甚至不需要什么时间。这也使您可以通过仅将更多项目放入列表中来向上扩展,而不必扩展您的任务。如果由于不能依赖列表顺序而需要编辑第一个任务,但是需要键入一个变量,则需要确保对第二个任务的磁盘也进行了更改,以免使用磁盘添加在第一个任务中。

此外,此模块上的文档指出,与此模块一起调用的现有磁盘将被调整为该大小,并且无法使用该模块进行缩小,因此,如果要避免这种情况,请进行一些数据检查以将配置的磁盘大小与变量中的大小进行比较,以便在要减少任务的情况下跳过任务(或者如果您不想更改现有的虚拟机)。