How to wait for DNS record?

55 views
Skip to first unread message

Pavel Martynov

unread,
Oct 18, 2018, 3:32:19 AM10/18/18
to Ansible Project
Hi!

I want to wait for some DNS record registered in DNS server. For example, A record. So I try to use this task:

- name: Wait DNS A record host.example.com registered
  set_fact:
    lookup_result: "{{ lookup('dig', 'host.example.com.') }}"
  until: lookup_result != 'NXDOMAIN'
  retries: 20
  delay: 3

But looks like lookup runs only single time at start and never again. I checked it with tcpdump:
$ sudo tcpdump udp port 53

Only single request/response on first loop iteration.
So, looks like lookup_result setted to value 'NXDOMAIN' and this value checked with effectively "until: 'NXDOMAIN' != 'NXDOMAIN'" 20 times without success.

How can I force run lookup on every loop iteration?

Ansible version 2.6.5

Thanks.

Pavel Martynov

unread,
Oct 18, 2018, 3:51:20 AM10/18/18
to ansible...@googlegroups.com
Actually, example without lookup at all:
- name: Test random
  set_fact:
    rand_result: "{{ 5 | random }}"
  until: rand_result == 'NEVER'
  retries: 10
  delay: 1

If I run ansible in verbose mode I see that on all iterations rand_result var have the same value, so jinja template evaluated once.
How can I force reevaluate it on every iteration?


чт, 18 окт. 2018 г. в 10:32, Pavel Martynov <mr.x...@gmail.com>:
--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To post to this group, send email to ansible...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/2ad1ad66-57d4-4029-8aac-e067205e3d2c%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


--
with best regards, Pavel Martynov

Karl Auer

unread,
Oct 18, 2018, 4:34:25 AM10/18/18
to ansible-project
Try this:

# Test random filter
- hosts: localhost

  tasks:

    - name: Test random
      set_fact:
         rand_result: "{{ 5 |random }}"
      with_sequence: count=10

Basically the change of item forces a re-evaluation, even though nothing is changing inside the loop.

However: You may still have a problem with DNS. A failed lookup (NXDOMAIN) will set a negative cache time on the result; no nameserver will issue a new query until the negative cache time has expired. The negative cache time is commonly set to values between five minutes and a few hours; very stable zones may set higher values. If the zone is under your control - which it looks like it is - set the negative cache time low when you are working on the zone. It's the last field in the SOA.

There are two ways around this. One way is to add "+trace" to your dig command to force the query to begin at the root every time. It is poor form to do this rapidly or frequently, so put a nice long pause between the name setup and your first attempt to check the new name (aim for the time it usually takes for a name to propagate for that zone), then use another nice long pause between checks - at least a minute. Checking once per second for an hour is very uncivilised indeed.

A better alternative is to do an SOA lookup, get the negative cache time value, add one minute, and use that as your pause time.

Regards, K.



For more options, visit https://groups.google.com/d/optout.


--
Karl Auer

Email  : ka...@2pisoftware.com
Website: http://2pisoftware.com


GPG/PGP : 958A 2647 6C44 D376 3D63 86A5 FFB2 20BC 0257 5816
Previous: F0AB 6C70 A49D 1927 6E05 81E7 AD95 268F 2AB6 40EA

Pavel Martynov

unread,
Oct 18, 2018, 5:33:15 AM10/18/18
to Ansible Project
четверг, 18 октября 2018 г., 11:34:25 UTC+3 пользователь Karl Auer написал:
Try this:

# Test random filter
- hosts: localhost

  tasks:
    - name: Test random
      set_fact:
         rand_result: "{{ 5 |random }}"
      with_sequence: count=10

Basically the change of item forces a re-evaluation, even though nothing is changing inside the loop.

I tried to use this:
- name: Wait DNS A record host.example.com registered
  set_fact:
    lookup_result: "{{ lookup('dig', 'host.example.com.') }}"
  until: lookup_result != 'NXDOMAIN'
  retries: 1
  delay: 3
  with_sequence: count=20

But the overall result of the task is a failure (I think this is because there is fail iterations at start).
Another flaw of this workaround is that task runs all 20 iterations even if there is DNS record, say, on 7 iteration (no 'break loop' logic).

I replace my task with this workaround:
- name: Wait DNS A record host.example.com registered
  command: "dig host.example.com +short"
  register: dig_result
  until: dig_result.stdout != ''
  retries: 20
  delay: 3

JFYI there is related issue on Github: https://github.com/ansible/ansible/issues/44128
 

However: You may still have a problem with DNS. A failed lookup (NXDOMAIN) will set a negative cache time on the result; no nameserver will issue a new query until the negative cache time has expired. The negative cache time is commonly set to values between five minutes and a few hours; very stable zones may set higher values. If the zone is under your control - which it looks like it is - set the negative cache time low when you are working on the zone. It's the last field in the SOA.


Yes, this is private zone under my control and negative cache already set to 60 seconds which is fine for me.

Karl Auer

unread,
Oct 18, 2018, 5:51:18 AM10/18/18
to ansible-project
Sorry, I wasn't suggesting you use a sequence! :-) That was just to illustrate the effect in a small test program.

I was just saying that to get the template re-evaluated you need to use a loop control that changes. Which you have achieved with a check of stdout.

Regards, K.

--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To post to this group, send email to ansible...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages