ansible: combine loop (until) with conditional (when)

audioslave picture audioslave · May 22, 2018 · Viewed 14.5k times · Source

I'm trying to install and configure an application server in a local vagrant vm. For the provisioning Ansible is used. The configuration can be done after the first start is finished. At this time it's listening on localhost:8000. After that I can copy the configuration file and restart the service. After that the port changes to 8081.

The thing is, I need to wait for the first start to be completed, before I override the config file. To check if the first start is done I used the url module in a loop, which works good. So the vm gets provisioned at the first vagrant up --provision.

But, if there's another vagrant provision and the Ansible playbook is doing the url module with the loop it's failing because of the changed port. So I tried this:

- name: configure / check for default server.conf


- command: grep "url.httpport=8081" "/{{ base_dir }}/conf/server.conf"
  ignore_errors: yes
  register: output

- name: configure / Check that app-server is installed successfully (8000)
  block:
    - get_url:
        url: http://localhost:8000/version.txt
        dest: /tmp
      register: result
      until: result is succeeded
      retries: 10
      delay: 30
      register: started
  when: output.rc == 1

- name: configure / Check that app-server is installed successfully (8081)
  block:
    - get_url:
        url: http://localhost:8081/version.txt
        dest: /tmp
      register: result
      until: result is succeeded
      retries: 10
      delay: 30
      register: started
  when: output.rc == 0

My idea is, that regarding to the return code, the correct block is chosen and the other one is skipped. But the result is this:

TASK [glue-tomcat8 : configure / check for default server.conf] ***
fatal: [devaws]: FAILED! => {"changed": true, "cmd": ["grep", ".url.httpport=8081", "/opt5/conf/server.conf"], "delta": "0:00:00.003016", "end": "2018-05-22 07:11:51.382776", "msg": "non-zero return code", "rc": 1, "start": "2018-05-22 07:11:51.379760", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
...ignoring

TASK [glue-tomcat8 : Check that app server is installed successfully (8000)] ***
fatal: [devaws]: FAILED! => {"msg": "The conditional check 'result is succeeded' failed. The error was: The failed test expects a dictionary"}

So, it seems, that there's a problem with the conditional check of the get_url module. When used alone, without when conditional (when) and not inside of a block, it's working. My guess is, that Ansible has issues with combining until and when. I can not find anything regarding this in the documentation. So any help is appreciated and thank you in advance.

Answer

audioslave picture audioslave · May 22, 2018

I got it working. It was a layer 8 (me) issue :) The variable started is a leftover and is not needed. Looks like Ansible was irritated by that variable. Here is my working code:

- command: grep "url.httpport=8081" "/{{ base_dir }}/conf/server.conf"
  ignore_errors: yes
  register: output

- get_url:
    url: http://localhost:8000/version.txt
    dest: /tmp
  register: result
  until: result is succeeded
  retries: 10
  delay: 30
  when: output.rc == 1

- get_url:
    url: http://localhost:8081/version.txt
    dest: /tmp
  register: result
  until: result is succeeded
  retries: 10
  delay: 30
  when: output.rc == 0