Introduction

AWX provides a REST API which allows to do pretty all commands that can be executed through the web interface, using http requests.

Sometimes is more easy to restart, or start jobs for instance through API, instead of going through the graphical interface.

First access of REST API

For instance, suppose the AWX server IP is 127.0.0.1.

Get some basic AWX server informations:

awxtest> curl -X GET -k https://127.0.0.1/api/ | jq .

{
  "description": "AWX REST API",
  "current_version": "/api/v2/",
  "available_versions": {
    "v2": "/api/v2/"
  },
  "oauth2": "/api/o/",
  "custom_logo": "",
  "custom_login_info": "",
  "login_redirect_override": ""
}

So the path to the API is /api/v2/ (checkout "v2": "/api/v2/" line)

Let’s get the list of all endpoints available:

awxtest> curl -X GET -k https://127.0.0.1/api/v2/ | jq .

{
  "ping": "/api/v2/ping/",
  "instances": "/api/v2/instances/",
  "instance_groups": "/api/v2/instance_groups/",
  "config": "/api/v2/config/",
  "settings": "/api/v2/settings/",
  ....
}

NOTE: I used jq to have a pretty print the JSON in a terminal. But is not necessary. Just nice to have.

How to list all jobs:

awxtest> curl -X GET --user admin:myadminpassword -k https://127.0.0.1/api/v2/job_templates/  | jq .
¨
{
  "id": 7,
  "type": "job_template",
  "url": "/api/v2/job_templates/7/",
  "related": {
    "named_url": "/api/v2/job_templates/Demo Job Template++Default/",
    "created_by": "/api/v2/users/1/",
    "modified_by": "/api/v2/users/1/",
    "labels": "/api/v2/job_templates/7/labels/",
    "inventory": "/api/v2/inventories/1/",
    "project": "/api/v2/projects/6/",
    "organization": "/api/v2/organizations/1/",
    "credentials": "/api/v2/job_templates/7/credentials/",
    "last_job": "/api/v2/jobs/2/",
    "jobs": "/api/v2/job_templates/7/jobs/",
    "schedules": "/api/v2/job_templates/7/schedules/",
    "activity_stream": "/api/v2/job_templates/7/activity_stream/",
	"launch": "/api/v2/job_templates/7/launch/",                                    
    "webhook_key": "/api/v2/job_templates/7/webhook_key/",
    "webhook_receiver": "",
    "notification_templates_started": "/api/v2/job_templates/7/notification_templates_started/",
    "notification_templates_success": "/api/v2/job_templates/7/notification_templates_success/",
    "notification_templates_error": "/api/v2/job_templates/7/notification_templates_error/",
    "access_list": "/api/v2/job_templates/7/access_list/",
    "survey_spec": "/api/v2/job_templates/7/survey_spec/",
    "object_roles": "/api/v2/job_templates/7/object_roles/",
    "instance_groups": "/api/v2/job_templates/7/instance_groups/",
    "slice_workflow_jobs": "/api/v2/job_templates/7/slice_workflow_jobs/",
    "copy": "/api/v2/job_templates/7/copy/"

There are pretty a lot of information here about the jobs, and also the endpoints to access these tasks.

In order to launch a job use the launch key: "launch": "/api/v2/job_templates/7/launch/" which gives you the URI to use to launch the job number 7.

Let’s get the job id to start the job.

awxtest>  curl -X POST --user admin:myadminpassword -k https://127.0.0.1/api/v2/job_templates/7/launch/ | jq .
...
"verbosity" : 0,  
"extra_vars" : "{}",  
"job" : 72,                                                                
"created" : "2018-11-20T11:09:49.813893Z", "force_handlers" : false,
... 

Here the job id is 72.

Start the job:

awxtest> curl -X GET --user admin:myadminpassword https://127.0.0.1/api/v2/jobs/72/ -k -s | jq .

Putting all together

Lets create an Ansible playbook to do all these steps in one.

---
- name: Tower API
  hosts: localhost
  become: false
  vars:
	  tower_user: admin
	  tower_pass: myadminpassword
	  tower_host: 127.0.0.1
	  tower_job_id: 7
	tasks:
  - name: Launch a new Job
    uri:
      url: https://{{ tower_host }}/api/v2/job_templates/{{ tower_job_id }}/launch/
      method: POST
      validate_certs: no
      return_content: yes
      user: "{{ tower_user }}"
      password: "{{ tower_pass }}"
      force_basic_auth: yes
      status_code: 201

Same playbook using a token for registration:

--
- name: Tower API

  hosts: localhost
  gather_facts: false

  vars:
    tower_user: admin
    tower_pass: myadminpassword
    tower_host: 127.0.0.1
    template_name: DEV template

  tasks:
    - name: Get the token
      uri:
        url: "https://{{ tower_host }}/api/v2/users/1/personal_tokens/"
        method: POST
        validate_certs: false
        return_content: true
        user: "{{ tower_user }}"
        password: "{{ tower_pass }}"
        force_basic_auth: true
        status_code: 201
      register: response

    - name: Use the token
      uri:
        url: "https://{{ tower_host }}/api/v2/job_templates/{{ template_name | urlencode }}/launch/"
        method: POST
        validate_certs: false
        return_content: true
        status_code: 201
        headers:
          Authorization: "Bearer {{ response['json']['token'] }}"
          Content-Type: "application/json"
      register: launch

Conclusion

AWX REST API is well designed and let you do almost all operation from command line. It is easy to create scripts to manage these operations. In the next blog I will explain how to get out all logs between two dates from AWX, and put them on the disk for an easy troubleshooting.


Share on