Question on wait_for

Hi,
I want to make a simple check after deploying an application with Ansible.
The task looks like this:

  • name: Wait for application to listen
    wait_for: host=localhost port={{ application_port }} state=started timeout=30
    tags:
  • check

I expect an HTTP server to listen on that port, and t check it myself I would use something like curl.

When I run it from my local machine, it works fine, but when it’s run on the CI server, this last step breaks after the timeout.
I have also seen this thing wrapped in the “local_action” module, but since the above example works, I do not think that’s the issue.
The only difference between CI run and me doing it locally is the remote_user, but I find it hard to image how that can possibly have anything to do with it., when only running the check.

There are probably many ways to solve the problem “Have Ansible exit with an error, if the deployment fails”, though this one is probably the easiest, so any hint is appreciated.

The error I am getting:

failed: [162.13.11.115] => {"elapsed": 34, "failed": true}
msg: Timeout when waiting for localhost:8000

This works:

  • name: Pausing to wait for application to start (fixed interval)
    pause: seconds=10
    tags:

  • check

  • name: Run curl
    command: curl localhost:8000
    register: run_curl
    tags:

  • check

  • name: Check curl output
    fail: msg=‘curl output was not as expected’

‘Not found’ is the expected content

when: “run_curl.stdout.find(‘Not Found’) == -1”
tags:

  • check

The wait_for module accepts a 'delay' parameter, so you don't need the
pause task.

http://docs.ansible.com/wait_for_module.html

Giovanni

Hi Giovanni!

Using wait_for did not work, that is why I changed to using pause. I would have preferred to use wait_for.
My question is: Under what circumstances would “wait_for: port=8000” fail, when “command: curl localhost:8000” (after waiting for the server) would succeed?

Thank you!

Even with the 'delay' parameter, wait_for still doesn't work? That would
make wait_for wait as many seconds as needed for the service to start,
so you avoid trying to connect uselessly (and possibly having to wait
for a timeout to expire).

If a pause fixes this for you, it could be a timing issue. The server
could be listening on the port but not accepting new connections yet, or
something related, I'm guessing.

Giovanni

Maybe Thomas should change wait_for conditions a little and wait until curl gets a page content instead of just checking port?

I’m not sure how to do this in ansible :frowning:

btw. Hi, I’m new here :wink: Greetings from Poland.

The issue can sometimes be caused by an app opens a port well before
it actually is capable of responding to traffic *stares at tomcat*,
this is usually the case when the main daemon runs as root to get
privileged resources (low ports, logs) and then changes to a lower
privileged user to do the work and it then has a slow loading
application *stares at jboss*.

@Giovanni: Yes the problem also happens, when I use wait_for with a delay

@Brian: Deploying a NodeJS application, normally it takes a few seconds for it to be ready. Also, everything is running with a dedicated non-root user.