Introduction
Ansible is a simple to use infrastructure automation tool and is used
for automating infrastructure, platform and deployments.
Playbooks and
roles are
defined for set of tasks and are executed to bring the state of
resources to desired state. One of things often needed for orchestrating
a non trivial deployment/platform creation is interacting with multiple
systems and extracting and combining information. These systems often
expose a REST API with JSON data. In this short tutorial we will look at
a way to process JSON outputs from REST APIs in Ansible playbooks.
We will use Github public API which is
free to use but limited at certain hit rate. Overall here is what we
will do:
- Hit the users endpoint of the API which will give a list of random
users.
- From the list of users, we will match the user with ID 3 and get the
name corresponding to that ID.
- We will use ID to form next URL and get email of the user from user
details API endpoint.
So let’s get started, you can check code used for this exercise
here. Once you check
out the code, you can simply run ‘ansible-playbook api.yml‘ from
within project directory assuming you have Ansible installed. The first
step is hitting the root endpoint of API to get a list of users:
- name: Running API
uri:
url: https://api.github.com/users
method: GET
return_content: yes
register: user_list
- name: App Details
debug: var=user_list
The above block will get the list of users which gets stored in
user_list variable using uri module of Ansible. You can also see the
content of the list as we are printing it out in next block. You will
notice the the content of user_list.json has the list of many users.
"user_list": {
"_content_encoding": "gzip",
"access_control_allow_origin": "*",
"date": "Wed, 10 Aug 2016 15:15:54 GMT",
"etag": "W/\"37cd21f64c9bddd3c1b4178f043300ac\"",
"json": [
{
"gravatar_id": "",
"html_url": "https://github.com/mojombo",
"id": 1,
"login": "mojombo",
"organizations_url": "https://api.github.com/users/mojombo/orgs",
"received_events_url": "https://api.github.com/users/mojombo/received_events",
"starred_url": "https://api.github.com/users/mojombo/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/mojombo/subscriptions",
"type": "User",
"url": "https://api.github.com/users/mojombo"
},
Ansible looping constructs
What we want to do with above data is retrieve the url for an user whose
“id” is 3 and then the URL of user will give email address of user in
turn. You can use looping
constructs in
Ansible along with conditionals to iterate through the JSON and filter
desired data. But the code will be lot of boilerplate and not cleanest
approach possible. We want a cleaner way to extract the data from JSON
while also reducing the boilerplate code and possibly separate that
logic into a separate block/file. One of ways to achieve that is to
use Jinja templates. Let’s first
call a jinja template and we expect the output of jinja template
rendering to be the URL of user with ID 3.
Now let’s code the jinja template which will iterate over the JSON and
conditionally check for user with ID 3. The file named app.yml.j2 has
code below:
We used the “-“ in every block to ensure trimming of white spaces which
are not needed. This will set the user\_url variable to the URL of the
user. We can make another HTTP request to retrieve details of user and
filter email of the user:
```yaml
- name: Using username
uri:
url: ""
method: GET
return_content: yes
register: user_details
- name: User Email
debug: var=user_details.json.email
And finally we get desired output:

Ansible is a powerful tool for automation and orchestration and a
templating engine such as Jinja can make it all the more useful and
clear for certain tasks.
Looking for help with building your DevOps strategy or want to outsource DevOps to the experts? learn why so many startups & enterprises consider us as one of the best DevOps consulting & services companies.