我正在构建一本可在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 }}"
答案 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
以下内容将在大约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。