Bookmark this page

Launching Jobs with the Automation Controller API

Objectives

  • Control automation controller by accessing its API.

The Automation Controller REST API

Automation controller provides a Representational State Transfer (REST) API that allows you to control automation controller without using the web UI. Custom scripts or external applications use standard HTTP messages to access the REST API. The REST API is useful if you want to integrate automation controller with other programs or make automated changes to automation controller.

One of the benefits of the REST API is that any programming language, framework, or system that supports HTTP can use the API. This provides a way to automate repetitive tasks and integrate other enterprise IT systems with automation controller.

Note

The API is in active development, and some features of the web UI might not be accessible through the API. Version 2 is the only version of the API currently available.

Using the REST API

In case you are not familiar with REST APIs, the way they work is relatively straightforward.

A web client sends a request to a server element located at a Uniform Resource Identifier (URI) and performs operations with standard HTTP methods, such as GET, POST, PUT, PATCH, and DELETE. The REST architecture provides a stateless communication channel between the client and the server. Each client request acts independently of any other request, and contains all the necessary information to complete the request.

The following example request uses an HTTP GET method to retrieve a representation of the main entry point of the API. You can use a graphical web browser or Linux command-line tools to issue the request manually. This example uses the curl command to make the request from the command line:

[user@demo ~]$ curl -X GET https://automation.example.com/api/ -k
{"description":"AWX REST API","current_version":"/api/v2/","available_versions":
{"v2":"/api/v2/"},"oauth2":"/api/o/","custom_logo":"","custom_login_info":"",
"login_redirect_override":""}

The output of the API request is in JSON format, which is readily parsable by computer programs, but might be a little challenging for a human to read.

The automation controller API is browsable. For example, if your automation controller is the automation.example.com host, you can access the browsable API at https://automation.example.com/api/. You can click the /api/v2/ link on that page to browse information specific to version 2 of the API.

The following example shows how to do this using the curl command. The jq command is provided by the jq RPM package and "pretty-prints" the JSON output of the API for easier reading.

[user@demo ~]$ curl -X GET https://automation.example.com/api/v2/ -k -s | jq .
{
  "ping": "/api/v2/ping/",
  "instances": "/api/v2/instances/",
  "instance_groups": "/api/v2/instance_groups/",
  "config": "/api/v2/config/",
  "settings": "/api/v2/settings/",
  "me": "/api/v2/me/",
  "dashboard": "/api/v2/dashboard/",
  "organizations": "/api/v2/organizations/",
  "users": "/api/v2/users/",
  "execution_environments": "/api/v2/execution_environments/",
  "projects": "/api/v2/projects/",
  "project_updates": "/api/v2/project_updates/",
  "teams": "/api/v2/teams/",
  "credentials": "/api/v2/credentials/",
  "credential_types": "/api/v2/credential_types/",
  "credential_input_sources": "/api/v2/credential_input_sources/",
  "applications": "/api/v2/applications/",
  "tokens": "/api/v2/tokens/",
  "metrics": "/api/v2/metrics/",
  "inventory": "/api/v2/inventories/",
  "inventory_sources": "/api/v2/inventory_sources/",
  "inventory_updates": "/api/v2/inventory_updates/",
  "groups": "/api/v2/groups/",
  "hosts": "/api/v2/hosts/",
  "job_templates": "/api/v2/job_templates/",
  "jobs": "/api/v2/jobs/",
  "ad_hoc_commands": "/api/v2/ad_hoc_commands/",
  "system_job_templates": "/api/v2/system_job_templates/",
  "system_jobs": "/api/v2/system_jobs/",
  "schedules": "/api/v2/schedules/",
  "roles": "/api/v2/roles/",
  "notification_templates": "/api/v2/notification_templates/",
  "notifications": "/api/v2/notifications/",
  "labels": "/api/v2/labels/",
  "unified_job_templates": "/api/v2/unified_job_templates/",
  "unified_jobs": "/api/v2/unified_jobs/",
  "activity_stream": "/api/v2/activity_stream/",
  "workflow_job_templates": "/api/v2/workflow_job_templates/",
  "workflow_jobs": "/api/v2/workflow_jobs/",
  "workflow_approvals": "/api/v2/workflow_approvals/",
  "workflow_job_template_nodes": "/api/v2/workflow_job_template_nodes/",
  "workflow_job_nodes": "/api/v2/workflow_job_nodes/",
  "mesh_visualizer": "/api/v2/mesh_visualizer/"
}

This entry point provides a collection of links in the API environment. As you can see in the example, many links are available.

Note

Other packages besides jq are available that can parse the JSON output in a human-readable way. For example, you can use the json_pp command provided by the perl-JSON-PP RPM package.

The following example illustrates some information accessible through the API. To examine what actions have been performed on automation controller, use the /api/v2/activity_stream/ URI. Make a GET request to that resource to retrieve the list of activity streams:

[user@demo ~]$ curl -X GET \
> https://automation.example.com/api/v2/activity_stream/ -k
{"detail":"Authentication credentials were not provided.
To establish a login session, visit /api/login/."}

Notice that not all information generated by the API is publicly available. You need to log in to access this resource.

The next example shows the output of the activity_stream resource when you provide correct authentication information (in this case, providing the password redhat for the admin account with the --user option):

[user@demo ~]$ curl -X GET --user admin:redhat \
> https://automation.example.com/api/v2/activity_stream/ -k -s | jq .
{
  "count": 45,
  "next": "/api/v2/activity_stream/?page=2",
  "previous": null,
  "results": [
    {
...output omitted...
    {
      "id": 23,
      "type": "activity_stream",
      "url": "/api/v2/activity_stream/23/",
      "related": {
        "execution_environment": [
          "/api/v2/execution_environments/6/"
        ]
      },
      "summary_fields": {
        "execution_environment": [
          {
            "id": 6,
            "name": "Automation Hub Default execution environment",
            "description": "",
            "image": "private.example.com/ee-supported-rhel8:latest"
          }
        ]
      },
      "timestamp": "2022-06-03T16:43:38.100345Z",
      "operation": "create",
      "changes": {
        "name": "Automation Hub Default execution environment",
        "description": "",
        "organization": null,
        "image": "private.example.com/ee-supported-rhel8:latest",
        "credential": null,
        "pull": "",
        "id": 6
      },
      "object1": "execution_environment",
      "object2": "",
      "object_association": "",
      "action_node": "automation.example.com",
      "object_type": ""
    },
...output omitted...

JSON Pagination

The JSON output of the API can be paginated. This divides the output into separate sequential pages that have similar content. Automation controller only returns a limited number of records from a particular request for performance reasons.

Review the first few lines of the preceding example, and notice the following information:

"next": "/api/v2/activity_stream/?page=2"
"previous": null

The next value gives you the URI of the next page of results. The previous value gives you the URI of the previous page of results. If the value for the previous page is null, then you are on the first page. Likewise, if the value for the next page is null, then you are on the last page.

In the same example as before, you can use the https://automation.example.com/api/v2/activity_stream/?page=2 URI to display the second page of the activity_stream resource. This updates the next and previous values:

  "next": null,
  "previous": "/api/v2/activity_stream/?page=1"

In this example the JSON output for the API of the activity_stream resource has two pages.

Accessing the REST API from a Graphical Web Browser

Because the output in JSON format for the API can be difficult to read without a parser such as jq, you can also access the browsable REST API with a graphical web browser. When you use a graphical web browser, you have the same information in a more readable format.

The following example shows the output of the activity_stream resource using the Firefox web browser. As before, if the resource provided by the API is not public, you need to log in to access that resource.

Figure 8.11: API output without authentication credentials

After you authenticate, you can perform the query for the resource that is not publicly available. The next and previous values and the exact number of pages shown in the output match the ones you had before, this time in an easier-to-read way.

Figure 8.12: Activity stream API output

You can click various links in the API to explore related resources.

Figure 8.13: Browsable API

Click the ? icon next to an API endpoint name to get documentation on the access methods for that endpoint. The documentation also provides information on what data is returned when using those methods.

Figure 8.14: Documentation for API endpoints

Note

The documentation available to graphical browsers through the ? icon is useful when you are trying to understand how to use the automation controller API.

You can also use PUT, POST, or PATCH methods on the specific API pages by providing JSON-formatted text or files in the graphical interface.

For example, you can put or patch content in the text field for the api/v2/settings/jobs API resource using your Firefox browser. After editing the content, click PUT to put the content or PATCH to patch it:

Figure 8.15: Example of PUT and PATCH methods text field

Launching a Job Template Using the API

One common use of the API is to launch an existing job template. This example outlines how to use the API to find and launch a job template that has already been configured in automation controller. It uses the curl command to interact with the API.

You can refer to a job template by name in the API. For example, you can use the GET method to get information about a job template. The following example illustrates how to use this method on the Demo Job Template job template. Because the name of the job template contains spaces, you must escape them using double quotes or URL percent encoding (%20 for each space character).

[user@demo ~]$ curl -X GET --user admin:redhat \
> https://automation.example.com/api/v2/job_templates/"Demo Job Template"/ \
> -k -s | jq .

Launching a job template from the API is done in two steps.

  1. Access the API with the GET method to get information about any parameters or data that you need to launch the job.

  2. Access the API with the POST method to launch the job.

The following example uses the GET method to get the parameters that you need to launch the Demo Job Template job template through the API. The output is piped into jq for better readability.

[user@demo ~]$ curl -X GET --user admin:redhat \
> https://automation.example.com/api/v2/job_templates/"Demo Job Template"/launch/\
>  -k -s | jq .
{
...output omitted...
  "defaults": {
    "extra_vars": "",
    "diff_mode": false,
    "limit": "",
    "job_tags": "",
    "skip_tags": "",
    "job_type": "run",
    "verbosity": 0,
    "inventory": {
      "name": "Demo Inventory",
      "id": 1
    },
    "credentials": [
      {
        "id": 1,
        "name": "Demo Credential",
        "credential_type": 1,
        "passwords_needed": []
      }
    ],
    "scm_branch": ""
  }
}

Note

For more detailed information, refer to the chapter on launching job templates in the "Automation Controller API Guide" in the references at the end of this section.

To launch the job, the job template or API call must provide the inventory ID, the inventory name, the credential ID and the credential name. The output of the previous example, which used the GET method, included all this information, so you would not need to provide it in your API call to launch the job template. You can launch the job by accessing the same URI with the POST method. In this example, the job with ID 1 reports "status": "pending" in the returned information about the job because it has been launched but has not completed yet.

[user@demo ~]$ curl -X POST --user admin:redhat \
> https://automation.example.com/api/v2/job_templates/"Demo Job Template"/launch/\
>  -k -s | jq .
{
  "job": 1,
  "ignored_fields": {},
  "id": 1,
  "type": "job",
  "url": "/api/v2/jobs/1/",
  ...output omitted...
  "created": "2022-06-16T22:16:56.384290Z",
  "modified": "2022-06-16T22:16:56.464627Z",
  "name": "Demo Job Template",
  "description": "",
  "job_type": "run",
  "inventory": 1,
  "project": 6,
  "playbook": "hello_world.yml",
  "scm_branch": "",
  "forks": 0,
  "limit": "",
  "verbosity": 0,
  "extra_vars": "{}",
  "job_tags": "",
  "force_handlers": false,
  "skip_tags": "",
  "start_at_task": "",
  "timeout": 0,
  "use_fact_cache": false,
  "organization": 1,
  "unified_job_template": 7,
  "launch_type": "manual",
  "status": "pending",
  "execution_environment": null,
...output omitted...

The JSON-formatted output of this example shows the id of this job is 1. You can use the job ID to retrieve updated status information, such as whether the job has completed. For job 1, use the URI /api/v2/jobs/1/, as indicated by the url field in the preceding output.

[user@demo ~]$ curl -X GET --user admin:redhat \
> https://automation.example.com/api/v2/jobs/1/ -k -s | jq .

This reports job status (success or failure), what time the job finished, a link to the output of the Ansible Playbook, which playbook was used, as well as other information about the inventory, credentials, and project from the job template, and more.

Note

You can also launch a job template using its internal ID number instead of its name.

First, find the id number of your job template. If you know the name of the job template, you can use the API to search for it. For example, if the desired job template is named A Job Template, you can search for it using the curl command:

[user@demo ~]$ curl -X GET --user admin:redhat \
> https://automation.example.com/api/v2/job_templates/?name=\
> "A Job Template" -k -s | jq .
...output omitted...
      "id": 6,
      "type": "job_template",
      "url": "/api/v2/job_templates/6/",
...output omitted...

You can now refer to the job template by its ID number and not its name, as follows:

[user@demo ~]$ curl -X POST --user admin:redhat \
> https://automation.lab.example.com/api/v2/job_templates/6/launch/ -k -s

Launching a Job Using the API from an Ansible Playbook

You can use an Ansible Playbook to launch a job template by using the uri module to access the automation controller API. You can even run that playbook from a job template in automation controller and use it to launch another job template as one of its tasks.

In the playbook, you have to specify the correct URL to your job template, using its ID or its named URL. You must also provide sufficient credentials to automation controller to authenticate as a user who has permission to launch the job.

The following Ansible Playbook can start a new job from one of the existing job templates in automation controller, using the automation controller API:

---
- name: Automation Controller API
  hosts: localhost
  become: false

  vars:
    automation_controller_user: admin 1
    automation_controller_pass: redhat
    automation_controller_host: automation.example.com
    automation_controller_job: Demo%20Job%20Template 2

  tasks:
    - name: Launch a new Job
      uri: 3
        url: https://{{ automation_controller_host }}/api/v2/job_templates/{{ automation_controller_job }}/launch/
        method: POST
        validate_certs: no
        return_content: yes
        user: "{{ automation_controller_user }}"
        password: "{{ automation_controller_pass }}"
        force_basic_auth: yes
        status_code: 201

1

To access the API, Ansible requires the login credentials for a user with sufficient permissions to launch a job from a job template. In the example, two variables are used to store the relevant information: automation_controller_user and automation_controller_pass.

2

The playbook also requires the URL of the actual API to which Ansible must connect. This example uses the named URL to the Demo Job Template. Notice how the spaces in the job template name have been specified using the %20 code. You can also use the urlencode filter: automation_controller_job: "{{ 'Demo Job Template' | urlencode }}".

3

Ansible can access the automation controller API from the automation controller server by using the uri module. As the uri module is part of ansible-core, you can refer to it using its module name, uri, without specifying the collection.

The problem with this example is that it embeds the username and password for authentication to automation controller in the playbook. To protect that data, you should either encrypt the playbook with Ansible Vault, or move the secrets into a variable file and encrypt that file with Ansible Vault. You should do this before you commit files containing those secrets to your source control repository.

[user@demo ~]$ ansible-vault encrypt api_demo.yml
New Vault password: your_password
Confirm New Vault password: your_password

Vault Credentials

For automation controller to use encrypted files (such as a playbook or an included variable file containing secrets), you must set up a Vault credential that can decrypt those files in automation controller. You must also configure any job templates that use the project with a Vault credential, in addition to any machine or other credentials that the project needs.

First, create a Vault credential that stores the Vault password for those files. This credential is encrypted and stored in the database of the automation controller server, just like the machine credentials.

The following procedure describes how to create this type of credential:

  • Log in to the automation controller web UI as a user with the appropriate role assignment. If you are creating a private credential, no specific role requirements apply. If you are creating an organization credential, log in as a user with the Admin role for the organization.

  • Click ResourcesCredentials.

  • Click Add to open the Create New Credential page.

Figure 8.16: New Vault credential
  • Enter a name for the new credential in the Name field.

  • If desired, enter a description for the Vault credential in the Description field.

  • If you have organization Admin privileges, click the search icon and select the organization name from the Select Organization dialog box to assign this credential to to make it an organization credential. If you do not have Admin privileges, do not select any organization.

  • Select Vault from the Credential Type list. Notice that additional fields are displayed in the Type Details section.

  • The Vault Password is the password with which you encrypted the playbook. This is a required field for Vault credentials.

  • The Vault Identifier is the optional Vault ID; only needed if the playbook has been encrypted using multiple passwords.

  • Click Save to save the new Vault credential.

After you have the Vault credential in place, you can create a new job template that uses it to decrypt your encrypted project file or files. This job template must include the Vault credential required to decrypt the project files.

Use the following procedure to include the Vault credential in the new job template:

  • Click the search icon in the Credentials field of the job template.

Figure 8.17: Selecting a credential for the job template
  • A pop-up window opens to select the credentials. Choose Vault in the Selected Category list.

  • Select the credential that corresponds to the job template.

  • Click Select to select the credential.

Figure 8.18: Vault credential for a job template

You can launch a job using the new job template. Automation controller decrypts the encrypted playbook using the Vault credential. When it runs the playbook, automation controller executes the task that accesses the API to launch another job template. This launches a new job on the automation controller server, using the job template referenced by the task in the playbook.

Note

In recent versions of Ansible, you can encrypt different files with different Ansible Vault passwords. Automation controller can use multiple Vault credentials in the same job template to ensure that it can decrypt all files in the project that were encrypted with Ansible Vault.

Token-based Authentication

The API for automation controller uses OAuth 2 to provide token-based authentication. Any call to the API with a valid token in the headers of the request can be authenticated.

Two kinds of tokens exist:

Application Tokens

Requested for an application that was previously created in automation controller, and represents a client application that accesses the API frequently with multiple users.

Personal Access Tokens (PATs)

PATs are a much simpler mechanism, providing access to the API for a single user.

This example shows a PAT request, as well as how to use the issued token to launch a job template.

---
- name: Automation Controller API
  hosts: localhost
  gather_facts: false

  vars:
    automation_controller_user: admin
    automation_controller_pass: redhat
    automation_controller_host: automation.example.com
    template_name: DEV ftpservers setup

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

    - name: Use the token
      uri:
        url: "https://{{ automation_controller_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'] }}" 3
          Content-Type: "application/json"
      register: launch

1

Use a regular authentication mechanism.

2

Save the result for later use.

3

Use the token in the response variable to provide the authentication.

Some token-related configurations are possible that you can set up from the automation controller web UI.

For example, you can configure the expiration date of the access token, or add the personal tokens for a user. Use the following procedure to add a new personal token for a user:

  • Log in to the automation controller web UI as your user.

  • Navigate to AccessUsers and then click Username.

  • Click the Tokens tab.

  • Click Add to add the new token.

  • In the Scope list, choose either Read or Write.

  • If desired, enter a description for the token.

  • If you are creating a PAT, leave the Application field empty. Otherwise, select the application for the token.

The following procedure describes how to modify the access and refresh expiration times for the token:

  • Log in to the automation controller web UI as the admin user.

  • Navigate to Settings.

  • On the System tile, click Miscellaneous Authentication settings.

  • Scroll to the bottom of the page and click Edit.

Figure 8.19: Configuring the expiration of an access token and its associated refresh token
  • Modify the Access Token Expiration or Refresh Token Expiration as required, and then click Save.

Revision: do467-2.2-08877c1