Search code examples
linuxansiblevmware

Conditionals against variables


I am building a snapshot management playbook and that checks for an existing snap before taking a snap. I am having trouble testing a conditional when the playbook finds an existing snap. Here is a sample code:

---
- name: Test Snapshot
  hosts: axwayT
  gather_facts: false
  
  vars_files:
    - vault/creds.yml

  vars:
    mail_body_file: "/tmp/ansible_mail"

  pre_tasks:

    - name: Delete mail body file
      file:
        state: absent
        path: "{{ mail_body_file }}"
      delegate_to: localhost
      run_once: true

    - name: Create mail body file
      file:
        state: touch
        path: "{{ mail_body_file }}"
      delegate_to: localhost
      run_once: true
    
  tasks:
    
    - name: find guest's folder using name
      vmware_guest_find:
        hostname: "{{ vcenter_hostname }}"
        username: "{{ vcenter_username }}"
        password: "{{ vcenter_password }}"
        validate_certs: no
        name: "{{ vcenter_hostgroup_name }}"
        datacenter: "{{ datacenter_name }}"
      register: vm_folder
      delegate_to: localhost
    
    - name: Check for existing snapshots
      vmware_guest:
         hostname: "{{ vcenter_hostname }}"
         username: "{{ vcenter_username }}"
         password: "{{ vcenter_password }}"
         validate_certs: no
         name: "{{ vcenter_hostgroup_name }}"
         datacenter: "{{ datacenter_name }}"
         folder: "{{vm_folder.folders[0]}}"
         name: "{{ vcenter_hostgroup_name }}"
         state: present
      register: vm_state
      delegate_to: localhost

    - name: debug
      debug:
        var: vm_state.instance.current_snapshot

    - name: Test
      shell: echo "Found!"
      when: vm_state.instance.current_snapshot !=""

I am working with an inventory of two servers for testing, nothing special. Here is the ouput I want to use a conditional against:

TASK [debug] ********************************************************************************************************************************************************************************************************************************
ok: [swipe901.test.com] => {
    "vm_state.instance.current_snapshot": ""
}
ok: [swipe902.test.com] => {
    "vm_state.instance.current_snapshot": {
        "creation_time": "2023-02-07T21:14:06.812901+00:00",
        "description": "",
        "id": 13,
        "name": "VM Snapshot 2%2f7%2f2023, 3:14:05 PM",
        "state": "poweredOn"
    }
}

I tried two when statements:

when: vm_state.instance.current_snapshot =""
when: vm_state.instance.current_snapshot is defined

My logic is way off and I am seeing my own limitations with programing logic, which I plan to fix soon.

My plan for the logic is to, skip a step, in my playbook if vm_state.instance.current_snapshot is "". How would this be handled?


Solution

  • Q: "I would like the condition to evaluate false if there is anything populated in current_snapshot."

    A: For example, the playbook

    shell> cat pb.yml
    - name: Evaluate false if there is anything populated in current_snapshot
      hosts: localhost
      tasks:
        - debug:
            msg: The variable current_snapshot is either empty or does not exist.
          when: current_snapshot|d('', true)|length == 0
    

    gives

    shell> ansible-playbook pb.yml
    
    PLAY [Evaluate false if there is anything populated in current_snapshot] *************************************************************
    
    TASK [debug] *************************************************************************************************************************
    ok: [localhost] => 
      msg: The variable current_snapshot is either empty or does not exist.
    
    PLAY RECAP ***************************************************************************************************************************
    localhost: ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
    
    shell> ansible-playbook pb.yml -e current_snapshot=''
    
    PLAY [Evaluate false if there is anything populated in current_snapshot] *************************************************************
    
    TASK [debug] *************************************************************************************************************************
    ok: [localhost] => 
      msg: The variable current_snapshot is either empty or does not exist.
    
    PLAY RECAP ***************************************************************************************************************************
    localhost: ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
    
    shell> ansible-playbook pb.yml -e current_snapshot='anything'
    
    PLAY [Evaluate false if there is anything populated in current_snapshot] *************************************************************
    
    TASK [debug] *************************************************************************************************************************
    skipping: [localhost]
    
    PLAY RECAP ***************************************************************************************************************************
    localhost: ok=0    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0
    

    You can also use assert. For example,

    shell> cat pb.yml
    - name: Evaluate false if there is anything populated in current_snapshot
      hosts: localhost
      tasks:
        - assert:
            that: current_snapshot|d('', true)|length == 0
            success_msg: The variable current_snapshot is either empty or does not exist.
            fail_msg: The variable current_snapshot is populated.