Check attempt count in runtime

16 views
Skip to first unread message

Zolvaring

unread,
Aug 6, 2019, 3:16:46 PM8/6/19
to Ansible Project
I'm trying to work with an API in an idempotent and DRY fashion and cannot find a way to do this for the life of me. What I want to do is hit an endpoint with POST, detect if the response indicates the resource already exists and, if so, hit it with a PUT on retry in order to make sure it's set properly.

What I have is this <> just for removing needless info:
- name: Configure my thing
  uri:
    url: https://{{ ansible_hostname }}:<api_endpoint>
    method: >-
      {% if results is defined and results.attempts is defined and results.attempts >= 1 -%}
        PUT
      {%- else -%}
        POST
      {% endif %}
    headers:
      <some headers>
    body: <body>
  loop: <series of requests>
  register: results
  retries: 1
  until: item is changed
  changed_when: item.status == 201
  failed_when:
    - item.status != 200
    - item.status != 201
    - item.status != 409


The condition is never triggered when I run the task and both retries end up with POST. I tried the simpler method jinja2 of "{% if results is not defined %}POST{% else %}PUT{% endif %} but this never triggers as well, and it seems like even on attempt 2 I cannot access `results` to actually trigger any useful modifications to task parameters.

I'd really appreciate any help if anyone knows what can sort me out here. I realize I can break this up into two or more tasks and have versions that do that but I am looking for the best solution here and to me that means DRY and I'm trying to avoid having multiple tasks or blocks for each action.

Zolvaring

unread,
Aug 6, 2019, 3:32:52 PM8/6/19
to Ansible Project
So I thought of a workaround using nested loops shortly after posting this. I'm going to leave this open because I think that being aware of retries in runtime should be possible, but I wanted to post the solution for anyone else stuck:

---
# file: tasks/main.yml

- name: Include API configuration items
  include_tasks: configure_api_item.yml
  loop: "{{ my_api_items }}"
  loop_control:
    loop_var:  __api_item


---
# file: tasks/configure_api_item.yml

- name: Configure API item
  uri:
    url: <endpoint>
    method: "{{ __method }}"
    headers:
      - <header1>
      - <header2>
    body: <body>
  loop:
    - POST
    - PUT
  register: __results
  changed_when: 
    - __results.status is defined
    - __results.status == 201
  failed_when:
    - __results.status is defined
    - __results.status != 200
    - __results.status != 201
    - __results.status != 409
Reply all
Reply to author
Forward
0 new messages