automationansibleopennebula

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


I want to deploy a few virtual machines in OpenNebula with Ansible. For example, I create vms with command/shell module (because there is no opennebula module in Ansible and I don't have sufficient qualification to write it):

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

But of course I need to check if there was already created vm with the same name and my solution looks like:

- 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 }}"

It is cumbersome in itself but furthermore on failure, I see a cumbersome output in 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.

Is there a more efficient method for solving this problem?


Solution

  • Here are some neat tricks for you:

    - 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 }}"
    

    Here we use shell && and || operators to print "Exists" if grep succeeded or execute onevm create if grep failed. Note that actual grep exit code is masked and module exit code is of echo or onevm create. This solves your problem of creating only VMs that doen't exist.

    Another thing is changed_when – this will ensure that Ansible print existing VMs in green and created in yellow. created_vms is a result of current iteration when used inside the loop, and populated with combined loop result when you use it after the current task.