VMware guest虚拟机可以使用ansible来确定其自己的名称和/或uuid吗?

时间:2019-08-06 22:15:55

标签: ansible vmware ansible-facts vcenter

我正在构建一本可在vcenter VM上运行的ansible剧本。它由ansible-pull在启动时运行。我的目标是使用ansible读取vm上的标签,然后基于这些标签对来宾系统进行一些配置更改。

困难在于我需要从来宾内部读取来宾上的标签。 vmware_guest_facts模块将允许我执行此操作,但是它需要来宾的名称或uuid。

目前,我唯一能看到的方法是使用vmware_vm_facts获取所有VM的事实,然后找到ansible_default_ipv4.address与IP地址匹配的VM,将其设置为一个事实,然后使用vmware_guest_facts进行读取通过UUID从该VM提取标签。似乎有点过分了。

VM是否有一种简单的方法来读取自己忽略的自己的标签?

这是我现在要做的:

- hosts: localhost
  connection: local

  vars_files:
    - vars.yaml

  pre_tasks:
    - name:  Read VMware vm facts
      vmware_vm_facts:
        hostname: "{{vc_host}}"
        password: "{{vc_pass}}"
        username: "{{vc_user}}"
        validate_certs: no
        vm_type: vm
      delegate_to: localhost
      register: vmfacts

    - name: scan for ip
      set_fact:
        vm_uuid: "{{ item.uuid }}"
        vm_name: "{{ item.guest_name }}"
      with_items: "{{ vmfacts.virtual_machines }}"
      when:
        - item.ip_address is defined
        - ansible_default_ipv4.address == item.ip_address


    - name:  Read VMware guest facts
      vmware_guest_facts:
        datacenter: ASDC
        hostname: "{{vc_host}}"
        uuid: "{{vm_uuid}}"
        password: "{{vc_pass}}"
        username: "{{vc_user}}"
        tags: yes
        validate_certs: no
      register: vmguestfacts


    - name:  set up tags var
      set_fact:
        vm_tags: "{{ vmguestfacts.instance.tags }}"

    - debug:
        msg: "{{ vm_tags }}"

2 个答案:

答案 0 :(得分:1)

我维护vmware_vm_facts并提高了PR https://github.com/ansible/ansible/pull/60220,以获取使用vmware_vm_facts的所有虚拟机的标签。使用此功能,您将能够收集VM标签。

PR合并后,任务将如下所示-

- name: Get Tags from given VM Name
  block:
    - name: Get virtual machine facts
      vmware_vm_facts:
        hostname: '{{ vcenter_hostname }}'
        username: '{{ vcenter_username }}'
        password: '{{ vcenter_password }}'
        folder: "/datacenter/vm/folder"
        show_tag: True
      delegate_to: localhost
      register: vm_facts

    - debug:
        msg: "{{ item.tags }}"
      with_items:
        - "{{ vm_facts.virtual_machines | json_query(query) }}"
      vars:
        query: "[?guest_name=='DC0_H0_VM0']"

答案 1 :(得分:0)

我上面发布的版本需要37秒才能运行,因为它正在请求vCenter上所有VM的信息。我发现dmidecode -s system-serial-number将以十六进制格式Serial Number: VMware-xx xx xx xx xx xx xx xx-xx xx xx xx xx xx xx xx

给出与虚拟机的uuid相匹配的系统序列号

以下内容将在大约7秒钟内运行:

- hosts: localhost
  connection: local

  vars_files:
    - vars.yaml

  pre_tasks:
    - name:  get uuid
      shell: |
        sudo /usr/sbin/dmidecode -s system-serial-number
      register: dmiout

    - set_fact:
        singleuuid: "{{ dmiout.stdout | regex_replace('.*VMware-(.*)$', '\\1') | replace(' ','') | replace('-','') }}"

    - set_fact:
        localuuid: "{{singleuuid[0:8]}}-{{singleuuid[8:12]}}-{{singleuuid[12:16]}}-{{singleuuid[16:20]}}-{{singleuuid[20:32]}}"

    - name:  Read VMware guest facts
      vmware_guest_facts:
        datacenter: ASDC
        hostname: "{{vc_host}}"
        uuid: "{{localuuid}}"
        password: "{{vc_pass}}"
        username: "{{vc_user}}"
        tags: yes
        validate_certs: no
      register: vmguestfacts


    - name:  set up tags var
      set_fact:
        vm_tags: "{{ vmguestfacts.instance.tags }}"

    - debug:
        msg: "{{ vm_tags }}"

唯一的收获是dmidecode需要root访问权限才能运行。由于这是以普通用户foouser的身份运行的,因此我必须将此行添加到sudoers中:

foouser ALL=(ALL) NOPASSWD:/usr/sbin/dmidecode

这整个过程都比我想要的笨拙,因此在下一次迭代中,我可能会将剧本更改为以root用户身份运行,这样就可以消除sudo的需要。

编辑:
有人问正则表达式是做什么的,所以这里有一些解释。我们从

开始
sudo /usr/sbin/dmidecode -s system-serial-number

返回

VMware-24 25 26 27 76 15 29 9d-0e 56 e5 b3 52 9f 41 a2

第一个regex_replace用任何内容替换了 VMware-,给了我们

24 25 26 27 76 15 29 9d-0e 56 e5 b3 52 9f 41 a2

第二次替换将不包含任何空格,从而给我们提供

242526277615299d-0e56e5b3529f41a2

第三个替换项将破折号替换为空,使我们获得

242526277615299d0e56e5b3529f41a2

下一行在正确的位置添加破折号以将其转换为有效的uuid。