I am trying to pass this curl command in ansible playbook :
shell: 'curl -k -u {{ AMBARI_USER }}:{{ AMBARI_PASSWORD }} -H 'X-Requested-By: ambari' -X POST -d '[{"Event": {"specs": [{"principal_type": "users", "sync_type": "all"}, {"principal_type": "groups", "sync_type": "all"}]}}]' https://{{AMBARI_SERVER_HOST}}:8083/api/v1/ldap_sync_events
here's my ansible playbook :
- hosts: adm
tasks:
- name: sync ldap
shell: "curl -k -u {{ AMBARI_USER }}:{{ AMBARI_PASSWORD }} -H 'X-Requested-By: ambari' -X POST -d '[{"Event": {"specs": [{"principal_type": "users", "sync_type": "all"}, {"principal_type": "groups", "sync_type": "all"}]}}]' https://{{AMBARI_SERVER_HOST}}:8083/api/v1/ldap_sync_events"
The thing is that this command has multiple double and simple cotes, so it's not wrking, is there anyway to pass it here or i should create a shell script for it ? Thanks
Is there a reason you're using plain shell commands instead of the uri
module? A general best practice is to prefer Ansible modules. They already fit to Ansible (e.g. change detection, error handling), save you work and may care about security if needed.
For example, in your case it avoids struggeling with multiple nested quotes, since it abstracts the parameters instead of having a large call. Raw shell commands should only be used in special cases, when the Ansible module doesn't work for the use case.
Something like this should fit for the base request using the uri
module:
- name: Make an API call
uri:
method: POST
url: "https://{{ AMBARI_SERVER_HOST }}:8083/api/v1/ldap_sync_events"
url_username: "{{ AMBARI_USER }}"
url_password: "{{ AMBARI_PASSWORD }}"
body_format: json
headers:
'X-Requested-By': 'ambari'
Several ways exists to pass the JSON body:
As string, which would be possible here since you don't need additional quotes as you needed for the curl
call.
Something like this could be used:
body: '[{"Event": ...'
A Ansible data structure like an array. Ansible would automatically convert it to JSON, as long as body_format
is set to the corresponding type as the case in my example above
From a file. I'd prefer this if the JSON is larger, because you can directly paste the object there and have proper formatting, without messing the Ansible part. Just use lookup
like this:
body: "{{ lookup('file','api-body.json') }}"
Just add the desired body
property to uri
. For example, If you want to have a json file, like this:
- name: Make an API call
uri:
method: POST
url: "https://{{ AMBARI_SERVER_HOST }}:8083/api/v1/ldap_sync_events"
url_username: "{{ AMBARI_USER }}"
url_password: "{{ AMBARI_PASSWORD }}"
body: "{{ lookup('file','api-body.json') }}"
body_format: json
headers:
'X-Requested-By': 'ambari'
# If you're interested in the response
return_content: yes
register: api_result