Search code examples
powershellansible

How to handle ok process when error thrown


I found the following approach to create the primary reverse zone for a Active Directory domain via Ansible:

- name: Create reverse DNS zone
  ansible.windows.win_shell: Add-DnsServerPrimaryZone -NetworkID {{ reverse_dns_zone }} -ReplicationScope Forest
  retries: 30
  delay: 60
  tags: debug
  until: result is succeeded

And I wanted to create a more idempotent approach. The only issue I have, running the command a second time, it always fails with:

Add-DnsServerPrimaryZone : Fehler beim Erstellen der Zone "0.3.10.in-addr.arpa" auf dem Server "DC01".
In Zeile:1 Zeichen:1
+ Add-DnsServerPrimaryZone -NetworkID 10.3.0.0/20 -ReplicationScope For ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ResourceExists: (0.3.10.in-addr.arpa:root/Microsoft/...rverPrimaryZone) [Add-DnsServerPrimaryZone], CimException
    + FullyQualifiedErrorId : WIN32 9609,Add-DnsServerPrimaryZone

Looking at CategoryInfo : ResourceExists I thought it could be a good success state for my approach, but using

until: result.stderr.find('ResourceExists') != -1

always results in a failed task.

What is the correct approach for such scenario?


Solution

  • You will have to take into account three different things in Ansible here:

    1. You want your until loop to repeat your task
    2. You want a failed_when condition that covers exceptions raised for other reasons than retrying
    3. You most likely want to know if the task as changed something or if the primary reverse zone was there already, which you can control with changed_when

    In this case, you also have to stop the until loop if the resource already exists:

    until: "result is succeeded or 'ResourceExists' in result.stderr"
    

    And your failed_when condition happens when you have an exception that does not contain ResourceExists:

    failed_when: "result.stderr != '' and 'ResourceExists' not in result.stderr" 
    

    While your changed_when will only happen when the task really succeed:

    changed_when: result is succeeded