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:
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"
},
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.
- set_fact:
user_url: ""
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.