在不编写新模块的情况下处理 Ansible 中的测试任务

Processing of test-tasks in Ansible without writing a new module

我想用 AnsibleOpenNebula 中部署一些虚拟机。 比如我用command/shell模块创建vms(因为没有opennebula Ansible中的模块,我没有足够的资格来编写它):

- name: Create VMs
  become_user: oneadmin
  command: onevm create --name "{{ item.1.name }}"
  with_items: "{{ vms }}"

但是我当然需要检查是否已经创建了同名的虚拟机,我的解决方案如下:

- name: Check what VMs already created
  become_user: oneadmin
  ignore_errors: yes
  shell: onevm list --csv | grep -q "{{ item.name }}"
  register: created_vms
  with_items: "{{ vms }}"
  loop_control:
    label: "Check if VM {{ item.name }} created"

- name: Create VMs
  become_user: oneadmin
  command: onevm create --name "{{ item.1.name }}"
  when: item.0|failed
  with_together:
    - "{{ created_vms.results }}"
    - "{{ vms }}"
  loop_control:
    label: "Create VM {{ item.1.name }}"

它本身很麻烦,而且在失败时,我在 Ansible 中看到了一个麻烦的输出:

TASK [create-vms : Check what VMs already created] 
************************************************
failed: [10.1.48.190] (item=Check if VM audit created) => {"changed": true, "cmd": "onevm list --csv | grep -q \"audit\"", "delta": "0:00:00.806504", "end": "2017-06-28 12:49:00.808454", "failed": true, "item": lalalalala etc.

有没有更有效的方法解决这个问题?

您正在使用 ignore_errors: yes,因此 ansible 将忽略错误,但由于 shell 任务的失败状态是 return 代码,任何失败的 grep 都会将项目转换为失败并显示它。

更好的解决方案是简单地获取 运行 VM 的列表,如果它们在第一个任务的输出中,则在第二个任务中跳过它们:

- name: Get running VMs
  become_user: oneadmin
  shell: onevm list --csv
  register: created_vms

- name: Create VMs
  become_user: oneadmin
  command: onevm create --name "{{ item.name }}"
  when: item not in created_vms.stdout
  with_items:
    - "{{ vms }}"
  loop_control:
    label: "Create VM {{ item.1.name }}"

这里有一些巧妙的技巧供您使用:

- name: Create VM if required
  become_user: oneadmin
  shell: onevm list --csv | grep -q "{{ item.name }}" && echo "Exists" || onevm create --name "{{ item.name }}"
  changed_when: created_vms.stdout != 'Exists'
  register: created_vms
  with_items: "{{ vms }}"

这里我们使用shell&&||运算符打印"Exists"如果grep成功或者执行onevm create如果grep 失败。请注意,实际 grep 退出代码被屏蔽,模块退出代码为 echoonevm create。这解决了您仅创建不存在的 VM 的问题。

另一件事是 changed_when – 这将确保 Ansible 以绿色打印现有 VM,以黄色创建。 created_vms 在循环内使用时是当前迭代的结果,在当前任务后使用它时填充组合循环结果。

感谢 Konstantin Suvorov 的回答!得出了类似的解决方案:

- name: Create VMs
  become_user: oneadmin
  shell: onevm list --csv | grep "{{ item.name }}" || onevm create --name "{{ item.name }}"
  register: created_vms
  changed_when: created_vms.stdout.find(item.name) == -1
  with_items: "{{ vms }}"
  loop_control:
    label: "Create VM {{ item.name }}"

希望对某人有用