繁体   English   中英

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

[英]Building a VM using Ansible Tower and I want to have the ability to create additional disks only when their variables are defined

我目前正在跨 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

ETC

看起来你应该用 1 个磁盘构建你的 vm,当你运行 play 时你肯定知道它总是在那里,你可以将它作为这个列表中的第一个变量:

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

由于我不知道您可以循环通过子模块 arguments 以使它们存在与否的方法,因此请使用您肯定会存在的一个磁盘构建您的虚拟机。 上面提到的,为了一致性,应该是你列表中的第一个。 或者,您将需要重新构建逻辑以深入到列表中以查找可以使用 jinja 过滤器(如 selectattr 和 map)键入的特定值。

- 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

这将通过一个循环将变量从您决定定义它的位置拉入,然后循环通过该字典列表提取具有正确标签的值,但只有在它们具有值时才这样做(如果在其中留下空白list 是你计划做的事情,如果没有,什么时候甚至不需要)。 这也将允许您通过在列表中添加更多项目来向上扩展,而无需扩展您的任务。 如果您因为不能依赖列表顺序而需要编辑第一个任务,但需要键入一个变量,那么您需要确保在第二个任务中也对磁盘进行更改以省略使用磁盘在第一个任务中添加。

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

可以使用过滤器default(omit) 省略参数

这样的事情应该可以解决问题:

   - size_gb: "{{ vm_disk_size3 | default(omit) }}"
     type: "{{ vm_disk_type3 | default(omit) }}"
     datastore: "{{ vm_disk_datastore3 | default(omit) }}"

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM