I am using the ansible URI module to talk to a REST api. I have a task to perform a GET to get me some data that i want to use later on. I want to be able to match a certain variable from the GET to create the path to do a PUT on the REST api. My code is as followed
playbook
*host_vars/host.yml
*
---
inputs:
- title: "test_input_api"
type: "org.graylog2.inputs.syslog.udp.SyslogUDPInput"
global: false
configuration:
allow_override_date: false
bind_address: "0.0.0.0"
expand_structured_data: false
force_rdns: false
number_worker_threads: 8
override_source: null
port: 5999
recv_buffer_size: null
store_full_message: true
- title: "test_input_api_2"
type: "org.graylog2.inputs.syslog.udp.SyslogUDPInput"
global: false
configuration:
allow_override_date: false
bind_address: "0.0.0.0"
expand_structured_data: false
force_rdns: false
number_worker_threads: 8
override_source: null
port: 5998
recv_buffer_size: null
store_full_message: true
playbook.yml
---
- name: Configure system
hosts: graylog
connection: local
gather_facts: no
roles:
- graylog/inputs
roles/graylog/inputs/tasks/main.yml
---
- include_tasks: get_inputs.yml
- include_tasks: put_inputs.yml
roles/graylog/inputs/tasks/get_inputs.yml
---
- name: "API GET System Inputs"
uri:
url: http://{{ ansible_host }}:9000/api/system/inputs
url_username : "{{ system.users.triple_admin.api_token }}"
url_password: token
method: GET
return_content: yes
register: get_graylog_inputs
- name: Set Fact
set_fact:
get_input_id: "{{ get_graylog_inputs.content | from_json | json_query('inputs[?title == `{}`] | [0].id '.format(input.title)) }}"
loop: "{{ inputs }}"
loop_control:
loop_var: input
roles/graylog/inputs/tasks/put_inputs.yml
---
- name: "API PUT System Inputs"
uri:
url: http://{{ ansible_host }}:9000/api/system/inputs/{{ get_input_id }}
url_username : "{{ system.users.triple_admin.api_token }}"
url_password: token
headers:
X-Requested-By: X-Ansible
method: PUT
body_format: json
body: "{{ lookup('template', 'templates/post_template.j2') }}"
status_code: 201
return_content: yes
loop: "{{ inputs }}"
loop_control:
loop_var: input
possible issue
A double loop statement within the play
As you can see in the get_inputs.yml I do a loop over the inputs dict in the host_vars within the set_fact task to get the ID from the REST api for each input entry that is defined in the host_vars that matches the title.
The idea behind this is when i want to change something about the input entry i can do a PUT that builds a path within the task put_inputs.yml the variable URL to the input with the id that is gathered with the GET and set to fact by the get_facts task and then play the PUT task to the rest api and adjust some parameter.
But i also need do a loop over the same inputs dict in the host_vars within the put_inputs.yml because if there are changes to multiple entries i want to loop the PUT.
The issue is that the get_facts get's both the id values as show below only the last one is being registered as the fact because it's a loop and they get the same name.
"ansible_facts": {
"get_input_id": "61015085eca1554750236084",
"get_input_titles": "test_input_api"
},
"ansible_facts": {
"get_input_id": "610282d0eca155475024ac91",
"get_input_titles": "test_input_api_2"
So when the put_inputs.yml task is played ( after the get_inputs.yml) I end up with the following response from the play which in short is that both times te task is being played ( as per loop ) i get the same get_input_id value.
loop 1 - this needs to be matched to the title and therefor get id "61015085eca1554750236084"
"title": "test_input_api",
"url": "http://192.168.21.82:9000/api/system/inputs/610282d0eca155475024ac91",
loop 2
"title": "test_input_api_2",
"url": "http://192.168.21.82:9000/api/system/inputs/610282d0eca155475024ac91",
Question
I need to get the ID from the GET because it's needed in the URL in the PUT task to edit a specific "input" entry. But because i need to match the ID to the Title i need to do a loop but this as I said previously results in only getting one ID value as a fact which is being used in the PUT loop for all items in the inputs dict this is not what i need because i need to be able to edit every entry separately based on ID.
All help is welcome !