[#]: subject: "Using Ansible with REST APIs" [#]: via: "https://opensource.com/article/21/9/ansible-rest-apis" [#]: author: "Vince Power https://opensource.com/users/vincepower" [#]: collector: "lujun9972" [#]: translator: " " [#]: reviewer: " " [#]: publisher: " " [#]: url: " " Using Ansible with REST APIs ====== You may have queried APIs with a web browser or curl, but one of the overlooked capabilities of Ansible is how well it can leverage APIs as part of any playbook. ![Looking at a map][1] Ansible is a top open source project which, on the surface, looks to provide a simple way to standardize your existing automation and allow it to run in parallel across multiple hosts, and it does this very successfully. Yet, in reality, Ansible has the capabilities to extend what your existing automation does to incorporate other systems and really simplify tasks across all aspects of your daily routine. This capability starts with the [collections][2] and [roles][3] that are included with Ansible and all the third-party utilities distributed through [Ansible Galaxy][4]. You may have queried APIs with a web browser or [curl][5], but one of the overlooked capabilities of Ansible is how well it can leverage APIs as part of any playbook. This is extremely useful because the number of REST APIs being built and deployed both internally and across the global internet is increasing exponentially. There's even a [public-apis GitHub repo][6] listing hundreds of free APIs across over a dozen categories just for a sense of scale. ### A basic API playbook Well, it really comes down to a few key core capabilities within Ansible, which are exposed nicely with one specific built-in task, _uri_. In this post, I'll go through a fairly simple example of how to call a REST API and use the data from that call to decide what to do next. This works with Ansible 2.9 and higher. In later versions (specifically v4), the modules we use need to be prepended with _ansible.builtin_ like _ansible.builtin.set_fact_ instead of just _set_fact_. To get started, you need a basic playbook to build on. In this case, you're only using local calls, so you don't need to be a superuser. First, create this YAML file to establish a working baseline: ``` \--- \- name: Using a REST API   become: false   hosts: localhost   gather_facts: false   tasks:     - debug:         msg: “Let’s call an API” ``` Here's the output after running it: ``` % ansible-playbook using-a-rest-api.yml PLAY [Using a REST API] ********************************************************************************************* TASK [debug] ******************************************************************************************************** ok: [localhost] => {     "msg": "“Let’s call an API”" } PLAY RECAP ********************************************************************************************************** localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   ``` ### Calling an API To call an actual API, you can use the _uri_ module. Here are two examples. The first is just a GET and the second is a POST with parameters to show the different available options. ``` \--- \- name: Everyone loves a good Chuck Norris joke   uri:     url:     method: GET \- name: Login to an API   uri:     url:     method: POST     body_format: json     body:       name: your_username       password: your_password       client_id: YOUR_CLIENT_ID       access_token: ACCESS_TOKEN       connection: CONNECTION       scope: SCOPE ``` I use the first API for the rest of this article to show how the returned data can be used. The question is, how do you collect the data being returned, and what does it look like? To collect the output from any task running in Ansible, you use the _register_ attribute, and then you can use the _debug_ task to display the raw data. In the case of APIs called using _uri_, all the output is put under the .json. Subsection of the result. The _uri_ commands and other its output are also at that top level. These can be useful to make sure the API call works by looking at other data fields like status. These are the two tasks you must add to the original playbook to add the API call to the mix to later do something with. ```   - name: Getting the definition of awesome       uri:         url:         method: GET       register: results     - debug:         var: results ``` Run it to see the output generated by debug: ``` TASK [debug] ******************************************************************************************************** ok: [localhost] => {     "results": {         "alt_svc": "h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400, h3-28=\":443\"; ma=86400, h3-27=\":443\"; ma=86400",         "cf_cache_status": "DYNAMIC",         "cf_ray": "694f7d791aeb19e7-EWR",         "changed": false,         "connection": "close",         "content_type": "application/json;charset=UTF-8",         "cookies": {},         "cookies_string": "",         "date": "Sun, 26 Sep 2021 21:12:23 GMT",         "elapsed": 0,         "expect_ct": "max-age=604800, report-uri=\""",         "failed": false,         "json": {             "categories": [],             "created_at": "2020-01-05 13:42:26.991637",             "icon_url": "",             "id": "IjqNNWKvSDeVKaI82PaT1g",             "updated_at": "2020-01-05 13:42:26.991637",             "url": "",             "value": "One person stated that Chuck Norris has forgotten more about killing than anyone will ever know. That is not true -- Chuck Norris never forgets. Ever."         },         "msg": "OK (unknown bytes)",         "nel": "{\"success_fraction\":0,\"report_to\":\"cf-nel\",\"max_age\":604800}",         "redirected": false,         "report_to": "{\"endpoints\":[{\"url\":\"https:\\\/\\\/a.nel.cloudflare.com\\\/report\\\/v3?s=HVPJYMVr%2B3wB1HSlgxv6GThBMjkBJgfdu0DPw%2BunjQzQ9YfXZqifggIJ%2FxOIKgOu6JP1SrPsx1jCCp3GQ9hZAp7NO0pmlTZ0y3ufbASGwLmCOV1zyaecUkSwQD%2Fv3RYYgZTkaSQ%3D\"}],\"group\":\"cf-nel\",\"max_age\":604800}",         "server": "cloudflare",         "status": 200,         "transfer_encoding": "chunked",         "url": "",         "via": "1.1 vegur"     } } ``` Now that you can see all the output make a custom message listing the value returned by the API. Here is the completed playbook: ``` \--- \- name: Using a REST API   become: false   hosts: localhost   gather_facts: false   tasks:     - debug:         msg: “Let’s call an API”     - name: Everyone loves a good Chuck Norris joke       uri:         url:         method: GET       register: results     - debug:         var: results.json.value ``` And now the complete output: ``` PLAY [Using a REST API] ********************************************************************************************* TASK [debug] ******************************************************************************************************** ok: [localhost] => {     "msg": "“Let’s call an API”" } TASK [Everyone loves a good Chuck Norris joke] ********************************************************************** ok: [localhost] TASK [debug] ******************************************************************************************************** ok: [localhost] => {     "results.json.value": "Chuck Norris is the only computer system that beats a Mac or a PC. Too bad all it does is round house kicks the user." } PLAY RECAP ********************************************************************************************************** localhost                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   ``` ### Next steps Things can get much more complicated than I've shown here. To get more details, head over to Ansible's [documentation][7]. -------------------------------------------------------------------------------- via: https://opensource.com/article/21/9/ansible-rest-apis 作者:[Vince Power][a] 选题:[lujun9972][b] 译者:[译者ID](https://github.com/译者ID) 校对:[校对者ID](https://github.com/校对者ID) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 [a]: https://opensource.com/users/vincepower [b]: https://github.com/lujun9972 [1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/tips_map_guide_ebook_help_troubleshooting_lightbulb_520.png?itok=L0BQHgjr (Looking at a map) [2]: https://docs.ansible.com/ansible/latest/user_guide/collections_using.html [3]: https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html [4]: https://galaxy.ansible.com/ [5]: https://www.redhat.com/sysadmin/use-curl-api [6]: https://github.com/public-apis/public-apis [7]: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/uri_module.html