Ansible playbook shell 命令变量未定义

Ansible playbook shell 命令变量未定义

我的 ansible 脚本用于在 virsh 中部署虚拟机并使用 cobbler 安装它们。使用固定在 mac 地址上的 IP 地址。要做到这一点,需要 mac 地址。但我很难让 grep 命令的输出注册为变量 mac_address。变量保持未定义状态。

当临时运行命令时,它运行良好:

[root@pxecobbler test]# ansible pirate.rum.local -m shell -a 'virsh 
domiflist testvm3 | grep -o -E "([0-9a-f]{2}:){5}([0-9a-f]{2})"' 
pirate.rum.local | SUCCESS | rc=0 >>
52:54:00:ec:a5:49

在 ansible 剧本中它失败了,变量保持未定义:

- name: get MAC adres new VM
          shell: >
                  virsh domiflist {{ item.key }} | grep -o -E "([0-9a-f]{2}:){5}([0-9a-f]{2})"
          with_dict: "{{ guests }}"
          register: mac_address
        - debug:
          msg: "{{ mac_address }}"

错误信息:

fatal: [pirate.rum.local]: FAILED! => {"msg": "The task includes an 
option with an undefined variable. 
The error was: 'dict object' has no attribute 'stdout_lines'\n\nThe 
error appears to have been in '/root/virsh-create-vm/virsh-create- 
vm.yml': line 47, column 7,
but may\nbe elsewhere in the file depending on the exact syntax 
problem.\n\nThe offending line appears to be:\n\n      
 register: mac_address\n    - debug: var=\"{{ mac_address.stdout_lines }}\"\n      
^ here\nWe could be wrong, but this one looks like it might be an issue with\nmissing quotes. 
Always quote template expression brackets when they\nstart a value. For instance:\n\n    with_items:\n      
- {{ foo }}\n\nShould be written as:\n\n    with_items:\n      - \"{{ foo }}\"\n\nexception type: 
<class 'ansible.errors.AnsibleUndefinedVariable'>\nexception: 'dict object' has no attribute 'stdout_lines'"}
to retry, use: --limit @/root/virsh-create-vm/virsh-create-vm.retry

整个脚本:


- name: create VMs
  hosts: pirate.rum.local
  become: true
  vars_files:
    - vms.yml

  tasks:
    - name: get VM disks
      command: "ls {{ vm_location }}"
      register: disks
      changed_when: "disks.rc != 0"

    - name: create disk
      command: >
               qemu-img create -f qcow2 -o preallocation=metadata {{ vm_location }}/{{ item.key }}.qcow2 10G
      when: item.key not in disks.stdout
      with_dict: "{{ guests }}"

    - name: get list of VMs
      virt:
        command: "list_vms"
      register: vms

    - name: create vm
      command: >
                virt-install --name {{ item.key }}
               --memory {{ item.value.mem }} --vcpus {{ item.value.cpus }}
                --pxe --network network=nat,model=virtio \
                --disk {{ vm_location }}/{{ item.key }}.qcow2
               --noautoconsole --os-variant {{ item.value.os_type }}
      when: item.key not in vms.list_vms
      with_dict: "{{ guests }}"

    - name: get MAC adres new VM
      shell: >
              virsh domiflist {{ item.key }} | grep -o -E "([0-9a-f]{2}:){5}([0-9a-f]{2})"
      with_dict: "{{ guests }}"
      register: mac_address
    - debug:
        msg: "{{ mac_address }}"


  # new tasks sequence on PXECobbler
- name: Register new VM's on Cobbler PXE host
  hosts: pxecobbler.rum.local
  vars_files:
    - vms.yml

  tasks:
    - name: register new VM on PXE cobbler host mac {{ mac_address.stdout }}
      shell: >
              cobbler system add --name={{ item.key }} --profile=CentOS-7-x86_64  --interface=eth0 --mac={{ mac_address.stdout }}  --ip-address={{ item.value.ip }} --netboot-enabled=1 --static=1
      with_dict: "{{ guests }}"  

答案1

当你说它时with_dict,意味着你正在循环。register: mac_address你得到的不是一个简单的普通对象,而是一个由你的循环填充的数组。

尝试这样的操作:

  # new tasks sequence on PXECobbler
- name: Register new VM's on Cobbler PXE host
  hosts: pxecobbler.rum.local
  vars_files:
    - vms.yml

  - shell: echo {{ item.changed }} {{ item.stdout }}     # will print: True 00:11:22:33:44
    with_items: "{{ mac_address.results }}"
    register: b
  - debug:
      msg: "{{ b }}"

下次你输的时候,要特别注意把最基本的任务做对。你的问题是很多如果您按原样引用实际的 yml(它包含debug: var="{{ mac_address.stdout_lines }}"您未引用的内容),则会更简单。

相关内容