This article about the Ansible URI module. I have recently spend a lot of time around automation for AVI software defined load balancers and wanted to share some useful information about how to use Ansible to interacting with REST API’s. Please check out my other articles around AVI Networks.
Let’s start with the playbook:
--- - hosts: controller gather_facts: false roles: - { role: "config" }
The config role needs the following folders:
config/ ├── defaults # Useful for default variables ├── tasks # Includes Ansible tasks using the URI module ├── templates # Jinja2 json templates └── vars # Variables to load json j2 templates
I will use defaults just as an example for variables which I use in the task and the json template.
Here’s the content of defaults/main.yml:
--- dns_servers: - 8.8.8.8 - 8.8.4.4 dns_domain: domain.com ntp_servers: - 0.uk.pool.ntp.org - 1.uk.pool.ntp.org username: admin password: demo api_version: 17.2.11
Next the Json Jinja2 template, the example below is the system configuration from AVI load balancers but this can be any json content you want to push to a REST API, templates/systemconfiguration_json.j2:
{ "dns_configuration": { {% if dns_domain is defined %} "search_domain": "{{ dns_domain }}" {% endif %} {% if dns_servers is defined %} {% for item in dns_servers %} "server_list": [ { "type": "V4", "addr": "{{ item }}" } {% if not loop.last %} , {% endif %} {% endfor %} {% endif %} ] }, "ntp_configuration": { {% if ntp_servers is defined %} {% for item in ntp_servers %} "ntp_servers": [ { "server": { "type": "DNS", "addr": "{{ item }}" } } {% if not loop.last %} , {% endif %} {% endfor %} {% endif %} ] }, "portal_configuration": { "password_strength_check": true, "use_uuid_from_input": false, "redirect_to_https": true, "enable_clickjacking_protection": true, "enable_https": true, "disable_remote_cli_shell": false, "http_port": 80, "enable_http": true, "allow_basic_authentication": true, } }
After we have specified the default variables and created the j2 template, let’s continue and see how we load the json template into a single variables in vars/main.yml:
--- systemconfiguration_json: "{{ lookup('template', 'systemconfiguration_json.j2') }}"
The step is the task itself using the Ansible URI module, tasks/main.yml:
--- - block: - name: Config | Systemconfiguration | Configure DNS, NTP and Portal settings uri: url: "https://{{ ansible_host }}/api/systemconfiguration" method: PUT user: "{{ username }}" password: "{{ password }}" return_content: yes body: "{{ systemconfiguration_json }}" force_basic_auth: yes validate_certs: false status_code: 200, 201 timeout: 180 headers: X-Avi-Version: "{{ api_version }}" when: '( inventory_hostname == group["controller"][0] )'
I like to use blocks in my Ansible tasks because you can group your tasks and use a single WHEN statement when you have multiple similar tasks.
I hope you find this article useful and please try it out and let me now in the comments below if you have questions.
Continue and read the other parts of this little series:
Here you find the links to the other articles about Ansible URI module:
Great article, can you post an example of the output? So I can see what everything is doing 🙂