如何将磁盘添加到VMware';使用Ansible Official模块更高效地管理虚拟机主机? 环境 操作系统版本:CentOS 7.5 Ansible版本:2.8.4和python 2.7.5 ESXi和VCenter版本:6.5.2 目的

如何将磁盘添加到VMware';使用Ansible Official模块更高效地管理虚拟机主机? 环境 操作系统版本:CentOS 7.5 Ansible版本:2.8.4和python 2.7.5 ESXi和VCenter版本:6.5.2 目的,ansible,vmware,esxi,vcenter,Ansible,Vmware,Esxi,Vcenter,我已经完成了我的代码,但我想知道是否有更好的方法通过Ansible office module将磁盘添加到VM主机 我的方法 来自vmware\u来宾\u磁盘\u事实的返回消息 我的剧本 --- -主持人:全部 远程用户:kai 变成:是的 成为用户:root 方法:sudo 收集事实:真实 变量: vcenter\u主机:“vcenter 01” vcenter\u用户名:“TFGH\\kaikudou” vcenter\u密码:xxxxxxxxx 目标主机:“TFGH0001” 任务: -名

我已经完成了我的代码,但我想知道是否有更好的方法通过Ansible office module将磁盘添加到VM主机

我的方法 来自vmware\u来宾\u磁盘\u事实的返回消息 我的剧本
---
-主持人:全部
远程用户:kai
变成:是的
成为用户:root
方法:sudo
收集事实:真实
变量:
vcenter\u主机:“vcenter 01”
vcenter\u用户名:“TFGH\\kaikudou”
vcenter\u密码:xxxxxxxxx
目标主机:“TFGH0001”
任务:
-名称:获取虚拟机信息
vmware\u来宾\u磁盘\u事实:
主机名:“{vcenter_host}}”
用户名:“{vcenter_username}”
密码:{vcenter_password}}
验证证书:错误
数据中心:“{vcenter\u host}”
名称:“{target_host}}”
委托给:localhost
注册:虚拟机磁盘信息
#-名称:显示虚拟机\u磁盘\u信息
#调试:
#msg:{{vm_disk_info.guest_disk_facts['0'].backing_datastore}}”
-名称:将空列表设置为存储变量
设定事实:
all_scsi_number_list:[]#存储所有scsi设备编号的列表
scsi_0:[]#用于存储scsi 0的设备以计算数量的列表
scsi_1:[]#存储scsi 1设备的列表,用于计算数量
scsi_2:[]#存储scsi 2设备的列表,用于计算数量
scsi_3:[]#存储scsi 3设备的列表,用于计算数量
所有单元号列表:[]存储scsi控制器设备号的列表
-名称:数据存储的Set变量
设定事实:
host_数据存储:“{{vm_disk_info.guest_disk_facts['0'].backing_datastore}”
-名称:将scsi\U编号存储到所有scsi\U编号列表中
设定事实:
所有scsi编号列表:“{{所有scsi编号列表+[vm磁盘信息.来宾磁盘事实[item].控制器密钥]}”
循环:“{{vm\u disk\u info.guest\u disk\u facts.keys()}”
-名称:找到scsi_控制器0并存储到scsi_0中
设定事实:
scsi_0:“{{scsi_0+[item]}”
循环:“{all_scsi_number_list}”
时间:项==1000
-名称:找到scsi_控制器1并存储到scsi_1中
设定事实:
scsi_1:“{{scsi_1+[item]}”
循环:“{all_scsi_number_list}”
时间:项==1001
-名称:找到scsi_控制器2并存储到scsi_2中
设定事实:
scsi_2:“{{scsi_2+[item]}”
循环:“{all_scsi_number_list}”
时间:项==1002
-名称:找到scsi_控制器3并存储到scsi_3中
设定事实:
scsi_3:“{{scsi_3+[item]}”
循环:“{all_scsi_number_list}”
时间:项==1003
-名称:计算scsi的数量_*
设定事实:
scsi_0_编号:“{{scsi_0|length}”
scsi_1_编号:{{scsi_1|length}}”
scsi_2_编号:{{scsi_2|length}}”
scsi_3_编号:{{scsi_3|length}}”
-名称:验证scsi控制器的编号,因为快照也会使设备成本低于7以防止
设定事实:
scsi_编号:“{{item.src}}”
循环:

-{src:“0”,当:“{{(scsi_0_number我试图重新表述问题。这远远不够完美,因为它不会考虑编号中的“漏洞”(即从序列中删除的磁盘或控制器)。但我认为您当前的实现也不会。我的实现应该可以在变量分配少得多的情况下工作,如果没有更多可用的插槽,它将优雅地失败

  • 从guest获取磁盘信息(例如粘贴在var中)
  • 从信息中,循环已配置控制器的编号。对于每个控制器,记录其密钥、编号、设备数量和最大配置设备id
  • 从列表中提取具有可用插槽的第一个控制器
  • 如果失败,则创建一个空的控制器信息,增加scsi设备号;如果达到最大值,则失败
注意:我使用了json_查询,因此您需要
pip(3)在ansible controller机器上安装jmespath
,以运行该示例

剧本:

---
- name: My take to your vmware disk management question
  hosts: localhost
  gather_facts: false

  vars:
    # Info copied from your example.
    vcenter_host: "VCENTER01"
    vcenter_username: "TFGH\\kaikudou"
    vcenter_password: xxxxxxxxx
    target_host: "TFGH0001"

    # Max number of devices per scsi controller
    scsi_max_devices: 15
    # Max id for scsi controllers
    scsi_max_controller_id: 3

    # Calling the two following vars before getting facts will fail
    # but since we don't need to loop to get them they can be statically
    # declared in playbook vars
    scsi_controller_unique_keys: >-
      {{
        vm_disk_info.guest_disk_facts
        | dict2items
        | map(attribute='value.controller_key')
        | list
        | unique
        | sort
      }}
    host_datastore: "{{ vm_disk_info.guest_disk_facts['0'].backing_datastore }}"

    # Your example data to play with (minified, single line)
    # To take from module call return IRL.
    vm_disk_info: {"guest_disk_facts":{"0":{"backing_datastore":"VCENTER01_DS01","backing_eagerlyscrub":false,"backing_filename":"[VCENTER01_DS01] TCB0945/TFGH0001-000001.vmdk","backing_thinprovisioned":false,"backing_type":"FlatVer2","backing_uuid":"6000C294-d22d-06a9-c89b-119e13fffe33","backing_writethrough":false,"capacity_in_bytes":32212254720,"capacity_in_kb":31457280,"controller_key":1000,"key":2000,"label":"Hard disk 1","summary":"31,457,280 KB","unit_number":0},"1":{"backing_datastore":"VCENTER01_DS01","backing_eagerlyscrub":false,"backing_filename":"[VCENTER01_DS01] TFGH0001/TFGH0001_3.vmdk","backing_thinprovisioned":false,"backing_type":"FlatVer2","backing_uuid":"6000C293-ae37-30f6-b684-d5b2416ff2f8","backing_writethrough":false,"capacity_in_bytes":10737418240,"capacity_in_kb":10485760,"controller_key":1000,"key":2001,"label":"Hard disk 2","summary":"10,485,760 KB","unit_number":1}}}

  tasks:

    - name: Create a list holding all the info we need for each existing controller
      vars:
        scsi_controller_devices_query: >-
          [?to_string(value.controller_key)=='{{ controller_key }}'].value.unit_number[]
        scsi_controller_devices: >-
          {{
            vm_disk_info.guest_disk_facts |
            dict2items |
            json_query(scsi_controller_devices_query)
          }}
        # Construct object directly as json so that we retain int type for further comparison usage.
        current_controller: >-
          {
            "controller_number": {{ controller_number | int }},
            "controller_key": {{ controller_key | int }},
            "number_of_devices": {{ scsi_controller_devices | length | int }},
            "max_unit_number": {{ scsi_controller_devices | max | int }},
          }
      set_fact:
        scsi_controllers_info: "{{ scsi_controllers_info | default([]) + [current_controller] }}"
      loop: "{{ scsi_controller_unique_keys }}"
      loop_control:
        loop_var: controller_key
        index_var: controller_number

    - block:

        # Note: This was already sorted when we got controllers list in our first loop
        - name: "Extract first controller having less than {{ scsi_max_devices }} disks"
          set_fact:
            scsi_controller: >-
              {{
                (
                  scsi_controllers_info |
                  selectattr('number_of_devices', '<', scsi_max_devices) |
                  list
                ).0
              }}

      rescue:

        - name: Fail if we cannot add an other controller id
          # i.e.controllernumber of our last element in list is equal (or greater for tests) that scsi_max_controller_id
          fail:
            msg: All scsi controllers are full, disk cannot be added.
          when: scsi_controllers_info[-1].controller_number >= scsi_max_controller_id

        - name: Return an empty controller with incremented id
          set_fact:
            scsi_controller: >-
              {
                "controller_number": {{ scsi_controllers_info[-1].controller_number + 1 | int }},
                "controller_key": {{ scsi_controllers_info[-1].controller_key + 1 | int }},
                "number_of_devices": 0,
                "max_unit_number": -1,
              }


    - name: Show what the call to vmware_guest_disk would look like
      vars:
        vmware_guest_disk_params:
          hostname: "{{ vcenter_host }}"
          username: "{{ vcenter_username }}"
          password: "{{ vcenter_password }}"
          validate_certs: False
          datacenter: "{{ vcenter_host }}"
          name: "{{ target_host }}"
          disk:
            - size_gb: 2
              type: thin
              state: present
              datastore: "{{ host_datastore }}"
              # autoselect_datastore: True
              scsi_controller: "{{ scsi_controller.controller_number }}"
              unit_number: "{{ scsi_controller.max_unit_number + 1 }}"
              scsi_type: 'paravirtual'
      debug:
        msg: "{{ vmware_guest_disk_params }}"

---
-姓名:我对您的vmware磁盘管理问题的看法
主机:本地主机
收集事实:错误
变量:
#从您的示例复制的信息。
vcenter\u主机:“vcenter 01”
vcenter\u用户名:“TFGH\\kaikudou”
vcenter\u密码:xxxxxxxxx
目标主机:“TFGH0001”
#每个scsi控制器的最大设备数
scsi_最大设备数:15
#scsi控制器的最大id
scsi\u最大\u控制器\u id:3
#在获取事实之前调用以下两个变量将失败
#但因为我们不需要循环来获取它们,所以它们可以是静态的
#在剧本变量中声明
scsi\u控制器\u唯一\u密钥:>-
{{
虚拟机磁盘信息。来宾磁盘事实
|口述2项
|映射(attribute='value.controller\u key')
|名单
|独特的
|分类
}}
host_数据存储:“{{vm_disk_info.guest_disk_facts['0'].backing_datastore}”
#要使用的示例数据(缩小,单线)
#从模块调用返回IRL获取。
虚拟机磁盘信息:{“来宾磁盘事实”:{“0”:{“备份数据存储”:“VCENTER01\u DS01”,“备份文件名”:false,“备份文件名”:“[VCENTER01\u DS01]TCB0945/TFGH0001-000001.vmdk”,“备份文件提供”:false,“备份类型”:“FlatVer2”,“备份文件ID”:“6000C294-d22d-06a9-c89b-119e13fffe33”,“备份文件名”:false,“备份文件写入”:false,“容量单位:32720字节,”容量(单位:kb):31457280,“控制器密钥”:1000,“密钥”:2000,“标签”:“硬盘1”,“摘要”:“31457280 kb”,“单元号”:0},“1”:{“备份数据存储”:“VCENTER01_DS01”,“backing_-key”:false,“backing_文件名”:[VCENTER01_-DS01]TFGH0001/TFGH0001_3.vmdk”,“backing_-thinprovisionited”:false,“backing_-type”:“FlatVer2”,“backing_-uuid”:“6000C293-ae37-
---
  - hosts: all
    remote_user: kai
    become: yes
    become_user: root
    become_method: sudo
    gather_facts: true

    vars:
      vcenter_host: "VCENTER01"
      vcenter_username: "TFGH\\kaikudou"
      vcenter_password: xxxxxxxxx
      target_host: "TFGH0001"

    tasks:

    - name: get VM info
      vmware_guest_disk_facts:
        hostname: "{{ vcenter_host }}"
        username: "{{ vcenter_username }}"
        password: "{{ vcenter_password }}"
        validate_certs: False
        datacenter: "{{ vcenter_host }}"
        name: "{{ target_host }}"
      delegate_to: localhost
      register: vm_disk_info

    # - name: show vm_disk_info
    #   debug:
    #     msg: "{{ vm_disk_info.guest_disk_facts['0'].backing_datastore }}"

    - name: Set empty list to store varialbe
      set_fact:
        all_scsi_number_list: []  # A list to store all scsi device number
        scsi_0: []  # A list to store scsi 0's device for counting the quantity
        scsi_1: []  # A list to store scsi 1's device for counting the quantity
        scsi_2: []  # A list to store scsi 2's device for counting the quantity
        scsi_3: []  # A list to store scsi 3's device for counting the quantity
        all_unit_number_list: []  # A list to store the device number from scsi controller   

    - name: Set variable of datastore
      set_fact:
        host_datastore: "{{ vm_disk_info.guest_disk_facts['0'].backing_datastore }}"

    - name: Store scsi_number into all_scsi_number_list
      set_fact:
        all_scsi_number_list: "{{ all_scsi_number_list + [vm_disk_info.guest_disk_facts[item].controller_key] }}"
      loop: "{{ vm_disk_info.guest_disk_facts.keys() }}"

    - name: Find out scsi_controller 0 and store into scsi_0
      set_fact:
        scsi_0 : "{{ scsi_0 + [item] }}"
      loop: "{{ all_scsi_number_list }}"
      when: item == 1000

    - name: Find out the scsi_controller 1 and store into scsi_1
      set_fact:
        scsi_1 : "{{ scsi_1 + [item] }}"
      loop: "{{ all_scsi_number_list }}"
      when: item == 1001

    - name: Find out the scsi_controller 2 and store into scsi_2
      set_fact:
        scsi_2 : "{{ scsi_2 + [item] }}"
      loop: "{{ all_scsi_number_list }}"
      when: item == 1002

    - name: Find out the scsi_controller 3 and store into scsi_3
      set_fact:
        scsi_3 : "{{ scsi_3 + [item] }}"
      loop: "{{ all_scsi_number_list }}"
      when: item == 1003

    - name: Calcualte the quantity of scsi_*
      set_fact:
        scsi_0_number: "{{ scsi_0 | length }}"
        scsi_1_number: "{{ scsi_1 | length }}"
        scsi_2_number: "{{ scsi_2 | length }}"
        scsi_3_number: "{{ scsi_3 | length }}"

    - name: Verify the scsi controller's number because snapshot will also cost the device so less than 7 to prevent
      set_fact:
        scsi_number: "{{ item.src }}"
      loop:
        - { src: "0", when: "{{ (scsi_0_number <= '6' and scsi_0_number != '0') or (scsi_0_number == '0') }}" }
        - { src: "1", when: "{{ (scsi_1_number <= '6' and scsi_1_number != '0') or (scsi_1_number == '0') }}" }
        - { src: "2", when: "{{ (scsi_2_number <= '6' and scsi_2_number != '0') or (scsi_2_number == '0') }}" }
        - { src: "3", when: "{{ (scsi_3_number <= '6' and scsi_3_number != '0') or (scsi_3_number == '0') }}" }
      when: item.when

    # - name: Show scsi_number which we get
    #   debug:
    #     msg: "{{ scsi_number }}"

    - name: Change the scsi_number we obtained to 4 digit number
      set_fact:
        scsi_digit_number: "{{ item.src | int }}"
      loop:
        - { src: "1000", when: "{{ scsi_number == '0' }}" }
        - { src: "1001", when: "{{ scsi_number == '1' }}" }
        - { src: "1002", when: "{{ scsi_number == '2' }}" }
        - { src: "1003", when: "{{ scsi_number == '3' }}" }
      when: item.when

    # - name: Show scsi_digit_number which we get
    #   debug:
    #     msg: "{{ scsi_digit_number }}"

    - name: Check the number of devices from the scci_number we obtained
      set_fact:
        all_unit_number_list: "{{ all_unit_number_list + [vm_disk_info.guest_disk_facts[item].unit_number] }}"
      loop: "{{ vm_disk_info.guest_disk_facts.keys() }}"
      when: vm_disk_info.guest_disk_facts[item].controller_key == scsi_digit_number | int

    # - name: Show all_unit_number_list which we get
    #   debug:
    #     msg: "{{ all_unit_number_list | length | type_debug }}"

    - name: Find the max number in all_unit_number_list then plus 1 to add new disk
      set_fact:
        disk_number: "{{ all_unit_number_list | max + 1 }}"
      ignore_errors: yes

    - name: If we have to add new scsi controller then the all_unit_number_list will be empty list, so we need to prevent it failed
      set_fact:
        disk_number: 0
      when: all_unit_number_list | length == 0

    - name: add disk
      vmware_guest_disk:
        hostname: "{{ vcenter_host }}"
        username: "{{ vcenter_username }}"
        password: "{{ vcenter_password }}"
        validate_certs: False
        datacenter: "{{ vcenter_host }}"
        name: "{{ target_host }}"
        disk:
          - size_gb: 2
            type: thin
            state: present
            datastore: "{{ host_datastore }}"
            # autoselect_datastore: True
            scsi_controller: "{{ scsi_number | int }}"
            unit_number: "{{ disk_number | int }}"
            scsi_type: 'paravirtual'
---
- name: My take to your vmware disk management question
  hosts: localhost
  gather_facts: false

  vars:
    # Info copied from your example.
    vcenter_host: "VCENTER01"
    vcenter_username: "TFGH\\kaikudou"
    vcenter_password: xxxxxxxxx
    target_host: "TFGH0001"

    # Max number of devices per scsi controller
    scsi_max_devices: 15
    # Max id for scsi controllers
    scsi_max_controller_id: 3

    # Calling the two following vars before getting facts will fail
    # but since we don't need to loop to get them they can be statically
    # declared in playbook vars
    scsi_controller_unique_keys: >-
      {{
        vm_disk_info.guest_disk_facts
        | dict2items
        | map(attribute='value.controller_key')
        | list
        | unique
        | sort
      }}
    host_datastore: "{{ vm_disk_info.guest_disk_facts['0'].backing_datastore }}"

    # Your example data to play with (minified, single line)
    # To take from module call return IRL.
    vm_disk_info: {"guest_disk_facts":{"0":{"backing_datastore":"VCENTER01_DS01","backing_eagerlyscrub":false,"backing_filename":"[VCENTER01_DS01] TCB0945/TFGH0001-000001.vmdk","backing_thinprovisioned":false,"backing_type":"FlatVer2","backing_uuid":"6000C294-d22d-06a9-c89b-119e13fffe33","backing_writethrough":false,"capacity_in_bytes":32212254720,"capacity_in_kb":31457280,"controller_key":1000,"key":2000,"label":"Hard disk 1","summary":"31,457,280 KB","unit_number":0},"1":{"backing_datastore":"VCENTER01_DS01","backing_eagerlyscrub":false,"backing_filename":"[VCENTER01_DS01] TFGH0001/TFGH0001_3.vmdk","backing_thinprovisioned":false,"backing_type":"FlatVer2","backing_uuid":"6000C293-ae37-30f6-b684-d5b2416ff2f8","backing_writethrough":false,"capacity_in_bytes":10737418240,"capacity_in_kb":10485760,"controller_key":1000,"key":2001,"label":"Hard disk 2","summary":"10,485,760 KB","unit_number":1}}}

  tasks:

    - name: Create a list holding all the info we need for each existing controller
      vars:
        scsi_controller_devices_query: >-
          [?to_string(value.controller_key)=='{{ controller_key }}'].value.unit_number[]
        scsi_controller_devices: >-
          {{
            vm_disk_info.guest_disk_facts |
            dict2items |
            json_query(scsi_controller_devices_query)
          }}
        # Construct object directly as json so that we retain int type for further comparison usage.
        current_controller: >-
          {
            "controller_number": {{ controller_number | int }},
            "controller_key": {{ controller_key | int }},
            "number_of_devices": {{ scsi_controller_devices | length | int }},
            "max_unit_number": {{ scsi_controller_devices | max | int }},
          }
      set_fact:
        scsi_controllers_info: "{{ scsi_controllers_info | default([]) + [current_controller] }}"
      loop: "{{ scsi_controller_unique_keys }}"
      loop_control:
        loop_var: controller_key
        index_var: controller_number

    - block:

        # Note: This was already sorted when we got controllers list in our first loop
        - name: "Extract first controller having less than {{ scsi_max_devices }} disks"
          set_fact:
            scsi_controller: >-
              {{
                (
                  scsi_controllers_info |
                  selectattr('number_of_devices', '<', scsi_max_devices) |
                  list
                ).0
              }}

      rescue:

        - name: Fail if we cannot add an other controller id
          # i.e.controllernumber of our last element in list is equal (or greater for tests) that scsi_max_controller_id
          fail:
            msg: All scsi controllers are full, disk cannot be added.
          when: scsi_controllers_info[-1].controller_number >= scsi_max_controller_id

        - name: Return an empty controller with incremented id
          set_fact:
            scsi_controller: >-
              {
                "controller_number": {{ scsi_controllers_info[-1].controller_number + 1 | int }},
                "controller_key": {{ scsi_controllers_info[-1].controller_key + 1 | int }},
                "number_of_devices": 0,
                "max_unit_number": -1,
              }


    - name: Show what the call to vmware_guest_disk would look like
      vars:
        vmware_guest_disk_params:
          hostname: "{{ vcenter_host }}"
          username: "{{ vcenter_username }}"
          password: "{{ vcenter_password }}"
          validate_certs: False
          datacenter: "{{ vcenter_host }}"
          name: "{{ target_host }}"
          disk:
            - size_gb: 2
              type: thin
              state: present
              datastore: "{{ host_datastore }}"
              # autoselect_datastore: True
              scsi_controller: "{{ scsi_controller.controller_number }}"
              unit_number: "{{ scsi_controller.max_unit_number + 1 }}"
              scsi_type: 'paravirtual'
      debug:
        msg: "{{ vmware_guest_disk_params }}"