Ansible Tower

+
+

Table of Contents

+

Release Notes

@@ -452,19 +487,23 @@

Release Notes

v1.0.3

+

v1.0.4

+

10/2024

+

Rebuilt the app to server v51.0.0

+ +

v1.0.3

7/2021

Bug fix to handle results data

-

v1.0.2

+

v1.0.2

2/2021

Bug fix for paged results from templates, jobs, etc.

-

v1.0.1

+

v1.0.1

12/2020

App Host support

-

v1.0.0

+

v1.0.0

2/2020

Initial release

@@ -497,26 +536,90 @@

Requirements +

SOAR platform

+

The SOAR platform supports two app deployment mechanisms, Edge Gateway (also known as App Host) and integration server.

+

If deploying to a SOAR platform with an App Host, the requirements are:

    -
  • Resilient platform >= v36.0

  • -
  • An Integration Server running resilient_circuits>=30.0.0

    -
      -
    • To set up an Integration Server see: ibm.biz/res-int-server-guide

    • +
    • SOAR platform >= 51.0.0.

    • +
    • The app is in a container-based format (available from the AppExchange as a zip file).

    +

    If deploying to a SOAR platform with an integration server, the requirements are:

    +
      +
    • SOAR platform >= 51.0.0.

    • +
    • The app is in the older integration format (available from the AppExchange as a zip file which contains a tar.gz file).

    • +
    • Integration server is running resilient_circuits>=51.0.0.

    • +
    • If using an API key account, make sure the account provides the following minimum permissions:

      +
      + + + + + + + + + + + + + + +

      Name

      Permissions

      Org Data

      Read

      Function

      Read

      +
    +

    The following SOAR platform guides provide additional information:

    +
      +
    • Edge Gateway Deployment Guide or App Host Deployment Guide: provides installation, configuration, and troubleshooting information, including proxy server settings.

    • +
    • Integration Server Guide: provides installation, configuration, and troubleshooting information, including proxy server settings.

    • +
    • System Administrator Guide: provides the procedure to install, configure and deploy apps.

    • +
    +

    The above guides are available on the IBM Documentation website at ibm.biz/soar-docs. On this web page, select your SOAR platform version. On the follow-on page, you can find the Edge Gateway Deployment Guide, App Host Deployment Guide, or Integration Server Guide by expanding Apps in the Table of Contents pane. The System Administrator Guide is available by expanding System Administrator.

    +

+
+

Cloud Pak for Security

+

If you are deploying to IBM Cloud Pak for Security, the requirements are:

+
    +
  • IBM Cloud Pak for Security >= 1.10.16.

  • +
  • Cloud Pak is configured with an Edge Gateway.

  • +
  • The app is in a container-based format (available from the AppExchange as a zip file).

  • +
+

The following Cloud Pak guides provide additional information:

+
    +
  • Edge Gateway Deployment Guide or App Host Deployment Guide: provides installation, configuration, and troubleshooting information, including proxy server settings. From the Table of Contents, select Case Management and Orchestration & Automation > Orchestration and Automation Apps.

  • +
  • System Administrator Guide: provides information to install, configure, and deploy apps. From the IBM Cloud Pak for Security IBM Documentation table of contents, select Case Management and Orchestration & Automation > System administrator.

  • +
+

These guides are available on the IBM Documentation website at ibm.biz/cp4s-docs. From this web page, select your IBM Cloud Pak for Security version. From the version-specific IBM Documentation page, select Case Management and Orchestration & Automation.

+
+
+

Proxy Server

+

The app does support a proxy server.

+
+
+

Python Environment

+

Python 3.9, 3.11, and 3.12 are officially supported. When deployed as an app, the app runs on Python 3.11. +Additional package dependencies may exist for each of these packages:

+
    +
  • resilient_circuits>=51.0.0

  • +
  • resilient_lib>=51.0.0

  • +
+

Installation

-
-

App Host

-

All the components for running this integration in a container already exist when using the App Host app.

-

To install,

-
    -
  • Navigate to Administrative Settings and then the Apps tab.

  • -
  • Click the Install button and select the downloaded file: app-fn_ansible_tower-x.x.x.zip.

  • -
  • Go to the Configuration tab and edit the app.config file, editing the url, access credentials, etc.

    +
    +

    Install

    +
      +
    • To install or uninstall an App or Integration on the SOAR platform, see the documentation at ibm.biz/soar-docs.

    • +
    • To install or uninstall an App on IBM Cloud Pak for Security, see the documentation at ibm.biz/cp4s-docs and follow the instructions above to navigate to Orchestration and Automation.

    • +
    +
    +
    +

    App Configuration

    +

    The following table provides the settings you need to configure the app. These settings are made in the app.config file. See the documentation discussed in the Requirements section for the procedure.

    @@ -550,8 +653,6 @@

    App Host

    -
  • -

Integration Server

@@ -657,75 +758,816 @@

Uninstall +

Function - Ansible Tower Get Ad Hoc Command Results

+

Return the results of an ad hoc command job

+

screenshot: fn-ansible-tower-get-ad-hoc-command-results

+
Inputs: +

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

Type

Required

Example

Tooltip

incident_id

number

Yes

-

-

tower_job_id

number

Yes

-

Launched job Id for a job template

tower_save_as

select

Yes

-

-

+
+

+
+
Outputs: +

+

+

NOTE: This example might be in JSON format, but results is a Python Dictionary on the SOAR platform.

+
+
results = {
+    # TODO: Generate an example of the Function Output within this code block.
+    # To get the output of a Function:
+    #   1. Run resilient-circuits in DEBUG mode: $ resilient-circuits run --loglevel=DEBUG
+    #   2. Invoke the Function in SOAR
+    #   3. Gather the results using: $ resilient-sdk codegen -p fn_ansible_tower --gather-results
+    #   4. Run docgen again: $ resilient-sdk docgen -p fn_ansible_tower
+    # Or simply paste example outputs manually here. Be sure to remove any personal information
+}
+
+
+

+
+
Example Function Input Script: +

+

inputs.tower_job_id = row['job_id']
+inputs.tower_save_as = rule.properties.tower_save_as
+inputs.incident_id = incident.id
+
+
+

+
+
Example Function Post Process Script: +

+

import re
+
+if results.content:
+  finished = results.content['summary']['finished'].replace('T', ' ') if results.content['summary']['finished'] else None
+  
+  row['status'] = results.content['summary']['status']
+  row['completion_date'] = finished
+  
+  note = u"Job Id: {}\nStatus: {}\nTemplate Name: {}\nFinished: {}".format(results.inputs['tower_job_id'], results.content['summary']['status'],
+                                                                           results.content['summary']['name'], finished)
+  if not results.inputs['tower_save_as_attachment']:
+    note = note + u"\n".join(event.get("stdout") for event in results.content['events']['results'])
+    incident.addNote(re.sub(r'[\x00-\x7f]\[[0-9;]*m', r'', note)) # remove color hilighting
+  else:
+    attachment_name = u"{}_{}.txt".format(results.content['summary']['name'].replace(" ", "_"), results.inputs['tower_job_id'])
+    note = note + u"\nAttachment Name: {}".format(attachment_name)
+    incident.addNote(note)
+
+
+
+

+
+


-
-

Troubleshooting

-

There are several ways to verify the successful operation of a function.

-
-

Resilient Action Status

-
    -
  • When viewing an incident, use the Actions menu to view Action Status.

  • -
  • By default, pending and errors are displayed.

  • -
  • Modify the filter for actions to also show Completed actions.

  • -
  • Clicking on an action displays additional information on the progress made or what error occurred.

  • -
+
+

Function - Ansible Tower Get Job Results

+

Get the results of a complete job

+

screenshot: fn-ansible-tower-get-job-results

+
Inputs: +

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

Type

Required

Example

Tooltip

incident_id

number

Yes

-

-

tower_job_id

number

Yes

-

Launched job Id for a job template

tower_save_as

select

Yes

-

-

+
+

+
+
Outputs: +

+

+

NOTE: This example might be in JSON format, but results is a Python Dictionary on the SOAR platform.

+
+
results = {
+    # TODO: Generate an example of the Function Output within this code block.
+    # To get the output of a Function:
+    #   1. Run resilient-circuits in DEBUG mode: $ resilient-circuits run --loglevel=DEBUG
+    #   2. Invoke the Function in SOAR
+    #   3. Gather the results using: $ resilient-sdk codegen -p fn_ansible_tower --gather-results
+    #   4. Run docgen again: $ resilient-sdk docgen -p fn_ansible_tower
+    # Or simply paste example outputs manually here. Be sure to remove any personal information
+}
+
+
+

+
+
Example Function Input Script: +

+

inputs.tower_job_id = row['job_id']
+inputs.tower_save_as = rule.properties.tower_save_as
+inputs.incident_id = incident.id
+
+
+

+
+
Example Function Post Process Script: +

+

import re
+
+if results.content:
+  finished = results.content['summary']['finished'].replace('T', ' ') if results.content['summary']['finished'] else None
+  
+  row['status'] = results.content['summary']['status']
+  row['completion_date'] = finished
+  
+  note = u"Job Id: {}\nStatus: {}\nTemplate Name: {}\nFinished: {}".format(results.inputs['tower_job_id'], results.content['summary']['status'],
+                                                                           results.content['summary']['name'], finished)
+  if not results.inputs['tower_save_as_attachment']:
+    note = note + u"\n".join(event.get("stdout") for event in results.content['events']['results'])
+    incident.addNote(re.sub(r'[\x00-\x7f]\[[0-9;]*m', r'', note)) # remove color hilighting
+  else:
+    attachment_name = u"{}_{}.txt".format(results.content['summary']['name'].replace(" ", "_"), results.inputs['tower_job_id'])
+    note = note + u"\nAttachment Name: {}".format(attachment_name)
+    incident.addNote(note)
+
+
+
+

+
-
-

Resilient Scripting Log

-
    -
  • A separate log file is available to review scripting errors.

  • -
  • This is useful when issues occur in the pre-processing or post-processing scripts.

  • -
  • The default location for this log file is: /var/log/resilient-scripting/resilient-scripting.log.

  • -
+
+
+

Function - Ansible Tower List Job Templates

+

List available job templates. * Wildcard can be used to filter project and template names

+

screenshot: fn-ansible-tower-list-job-templates

+
Inputs: +

+

+ + + + + + + + + + + + + + + + + + + + + + + +

Name

Type

Required

Example

Tooltip

tower_project

text

No

-

Optionally filter by project. Supports * wildcard

tower_template_pattern

text

No

-

Use * to use wildcard matches

+
+

+
+
Outputs: +

+

+

NOTE: This example might be in JSON format, but results is a Python Dictionary on the SOAR platform.

+
+
results = {
+    # TODO: Generate an example of the Function Output within this code block.
+    # To get the output of a Function:
+    #   1. Run resilient-circuits in DEBUG mode: $ resilient-circuits run --loglevel=DEBUG
+    #   2. Invoke the Function in SOAR
+    #   3. Gather the results using: $ resilient-sdk codegen -p fn_ansible_tower --gather-results
+    #   4. Run docgen again: $ resilient-sdk docgen -p fn_ansible_tower
+    # Or simply paste example outputs manually here. Be sure to remove any personal information
+}
+
+
+

+
+
Example Function Input Script: +

+

inputs.tower_project = rule.properties.tower_project
+inputs.tower_template_pattern = rule.properties.tower_template_pattern
+
+
+

+
+
Example Function Post Process Script: +

+

import java.util.Date as Date
+if not results.content:
+  row = incident.addRow("ansible_tower_job_templates")
+  row['reported_on'] = str(Date())
+  row['template_name'] = "-- No results returned --"
+else:
+  for template in results.content:
+    row = incident.addRow("ansible_tower_job_templates")
+    row['reported_on'] = str(Date())
+    row['template_id'] = template['id']
+    row['template_name'] = template['name']
+    row['template_description'] = template['description']
+    row['template_project'] = template['summary_fields']['project']['name']
+    row['template_playbook'] = template['playbook']
+    row['template_last_run'] = template['last_job_run'].replace('T', ' ') if template['last_job_run'] else None
+
+
+

+
-
-

Resilient Logs

-
    -
  • By default, Resilient logs are retained at /usr/share/co3/logs.

  • -
  • The client.log may contain additional information regarding the execution of functions.

  • -
+
+
+

Function - Ansible Tower List Jobs

+

List Ansible Tower jobs based on job status and last modified conditions

+

screenshot: fn-ansible-tower-list-jobs

+
Inputs: +

+

+ + + + + + + + + + + + + + + + + + + + + + + +

Name

Type

Required

Example

Tooltip

tower_job_status

multiselect

No

-

Leave empty for all status values

tower_last_updated

select

No

-

specify timeframe to filter returned jobs

+
+

+
+
Outputs: +

+

+

NOTE: This example might be in JSON format, but results is a Python Dictionary on the SOAR platform.

+
+
results = {
+    # TODO: Generate an example of the Function Output within this code block.
+    # To get the output of a Function:
+    #   1. Run resilient-circuits in DEBUG mode: $ resilient-circuits run --loglevel=DEBUG
+    #   2. Invoke the Function in SOAR
+    #   3. Gather the results using: $ resilient-sdk codegen -p fn_ansible_tower --gather-results
+    #   4. Run docgen again: $ resilient-sdk docgen -p fn_ansible_tower
+    # Or simply paste example outputs manually here. Be sure to remove any personal information
+}
+
+
+

+
+
Example Function Input Script: +

+

inputs.tower_job_status = rule.properties.job_status
+inputs.tower_last_updated = rule.properties.last_updated
+
+
+

+
+
Example Function Post Process Script: +

+

import java.util.Date as Date
+for job in results.content:
+  run_row = incident.addRow('ansible_tower_launched_jobs')
+  
+  run_row['reported_on'] = str(Date())
+  run_row['type'] = 'template'
+  run_row['launch_date'] = job['created'].replace('T', ' ')
+  run_row['status'] = job['status']
+  run_row['job_id'] = job['id']
+  run_row['template_name'] = job['name']
+  run_row['project'] = job['summary_fields']['project']['name']
+  run_row['run_tags'] = job['job_tags']
+  run_row['skip_tags'] = job['skip_tags']
+  run_row['inventory'] = job['limit']
+  run_row['arguments'] = job['extra_vars'].replace("{", "").replace("}", "")
+  #run_row['ignored_fields'] = str(job['ignored_fields'])
+
+
+

+
-
-

Resilient-Circuits

-
    -
  • The log is controlled in the .resilient/app.config file under the section [resilient] and the property logdir.

  • -
  • The default file name is app.log.

  • -
  • Each function will create progress information.

  • -
  • Failures will show up as errors and may contain python trace statements.

  • -

+
+

Function - Ansible Tower Run an Ad Hoc Command

+

Run an ad hoc command through ansible tower

+

screenshot: fn-ansible-tower-run-an-ad-hoc-command

+
Inputs: +

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

Type

Required

Example

Tooltip

tower_arguments

text

No

name1=value;name2=value

Semicolon separated name/value pairs

tower_credential

number

Yes

-

-

tower_hosts

text

No

-

comma separated list of hosts to limit

tower_inventory

number

No

-

-

tower_module

select

No

-

-

+
+

+
+
Outputs: +

+

+

NOTE: This example might be in JSON format, but results is a Python Dictionary on the SOAR platform.

+
+
results = {
+    # TODO: Generate an example of the Function Output within this code block.
+    # To get the output of a Function:
+    #   1. Run resilient-circuits in DEBUG mode: $ resilient-circuits run --loglevel=DEBUG
+    #   2. Invoke the Function in SOAR
+    #   3. Gather the results using: $ resilient-sdk codegen -p fn_ansible_tower --gather-results
+    #   4. Run docgen again: $ resilient-sdk docgen -p fn_ansible_tower
+    # Or simply paste example outputs manually here. Be sure to remove any personal information
+}
+
+
+

+
+
Example Function Input Script: +

+

inputs.tower_module = rule.properties.ansible_tower_module
+inputs.tower_arguments = rule.properties.ansible_tower_module_arguments
+inputs.tower_hosts = rule.properties.ansible_tower_hosts
+
+inventory = rule.properties.ansible_tower_inventory
+if inventory.find('-') != -1:
+  inv_split = inventory.split("-")
+else:
+  inv_split = inventory.split(" ")
+inputs.tower_inventory = int(inv_split[0])
+
+credential = rule.properties.ansible_tower_credential
+if credential.find('-') != -1:
+  cred_split = credential.split("-")
+else:
+  cred_split = credential.split(" ")
+inputs.tower_credential = int(cred_split[0])
+
+
+

+
+
Example Function Post Process Script: +

+

import java.util.Date as Date
+
+run_row = incident.addRow('ansible_tower_launched_jobs')
+
+run_row["reported_on"] = str(Date())
+run_row['type'] = 'ad hoc'
+run_row['launch_date'] = results.content['created'].replace('T', ' ')
+run_row['status'] = results.content['status']
+run_row['job_id'] = results.content['id']
+run_row['template_name'] = results.content['name']
+run_row['inventory'] = results.content['limit']
+run_row['arguments'] = str(results.content['module_args']).replace("{", "").replace("}", "")
+
+
+
+

+
+
+
+
+

Function - Ansible Tower Run Job

+

Execute a job for a given tower template

+

screenshot: fn-ansible-tower-run-job

+
Inputs: +

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

Type

Required

Example

Tooltip

tower_arguments

text

No

name1=value;name2=value

Semicolon separated name/value pairs

tower_hosts

text

No

-

comma separated list of hosts to limit

tower_run_tags

text

No

-

Comma separated list of plays to run

tower_skip_tags

text

No

-

Comma separated list of plays to skip

tower_template_id

number

No

-

Job Template Id to launch

tower_template_name

text

No

-

Name of Job Template, optional to tower_template_id

+
+

+
+
Outputs: +

+

+

NOTE: This example might be in JSON format, but results is a Python Dictionary on the SOAR platform.

+
+
results = {
+    # TODO: Generate an example of the Function Output within this code block.
+    # To get the output of a Function:
+    #   1. Run resilient-circuits in DEBUG mode: $ resilient-circuits run --loglevel=DEBUG
+    #   2. Invoke the Function in SOAR
+    #   3. Gather the results using: $ resilient-sdk codegen -p fn_ansible_tower --gather-results
+    #   4. Run docgen again: $ resilient-sdk docgen -p fn_ansible_tower
+    # Or simply paste example outputs manually here. Be sure to remove any personal information
+}
+
+
+

+
+
Example Function Input Script: +

+

inputs.tower_template_name = rule.properties.ansible_tower_job_name
+inputs.tower_hosts = rule.properties.ansible_tower_hosts
+artifact_data = "artifact_value={};artifact_type={}".format(artifact.value, artifact.type)
+if rule.properties.ansible_tower_arguments:
+  inputs.tower_arguments = ";".join((rule.properties.ansible_tower_arguments, artifact_data))
+else:
+  inputs.tower_arguments = artifact_data
+inputs.tower_run_tags = rule.properties.ansible_tower_run_tags
+inputs.tower_skip_tags = rule.properties.ansible_tower_skip_tags
+
+
+

+
+
Example Function Post Process Script: +

+

import java.util.Date as Date
+if not results.content['failed']:
+  run_row = incident.addRow('ansible_tower_launched_jobs')
+  
+  run_row['reported_on'] = str(Date())
+  run_row['type'] = 'template'
+  run_row['launch_date'] = results.content['created'].replace('T', ' ')
+  run_row['status'] = results.content['status']
+  run_row['job_id'] = results.content['job']
+  run_row['template_name'] = results.content['name']
+  run_row['project'] = results.content['summary_fields']['project']['name']
+  run_row['run_tags'] = results.content['job_tags']
+  run_row['skip_tags'] = results.content['skip_tags']
+  run_row['inventory'] = results.content['limit']
+  run_row['arguments'] = str(results.content['extra_vars']).replace("{", "").replace("}", "")
+  run_row['ignored_fields'] = str(results.content['ignored_fields']).replace("{", "").replace("}", "")
+
+
+

+
+
+
+
+

Custom Layouts

+
    +
  • Import the Data Tables and Custom Fields like the screenshot below:

    +

    screenshot: custom_layouts

    +
  • +
+
+

Data Table - Ansible Tower Job Templates

+

screenshot: dt-ansible-tower-job-templates

+
+

API Name:

+

ansible_tower_job_templates

+
+
+

Columns:

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Column Name

API Access Name

Type

Tooltip

Description

template_description

text

-

Job Id

template_id

number

-

Last Run

template_last_run

text

-

Name

template_name

text

-

Playbook

template_playbook

text

-

Project

template_project

text

-

Reported On

reported_on

text

-

+
-
-

Configure Ansible Tower

-

No additional configuration is requirement for Ansible Tower.


-
-

Support

+
+

Data Table - Ansible Tower Launched Jobs

+

screenshot: dt-ansible-tower-launched-jobs

+
+

API Name:

+

ansible_tower_launched_jobs

+
+
+

Columns:

- - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

Version

Author

Support Email

Column Name

API Access Name

Type

Tooltip

Arguments

arguments

text

-

Completion Date

completion_date

text

-

Hosts

inventory

text

-

Ignored Fields

ignored_fields

text

-

Job Id

job_id

number

-

Launch Date

launch_date

text

Date Job was created

Name

template_name

text

Job Template Name

Project

project

text

-

Reported On

reported_on

text

Date row was added

Run Tags

run_tags

text

-

Skip Tags

skip_tags

text

-

Status

status

text

Status of Job

Type

type

text

‘ad hoc’, ‘template’

+
+
+
+
+
+

Rules

+
+ + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Rule Name

Object

Workflow Triggered

Condition

fn_ansible_tower

1.0.0

IBM Resilient

support@resilientsystems.com

Ansible Tower Get Ad Hoc Command Results

ansible_tower_launched_jobs

ansible_tower_get_ad_hoc_command_results

ansible_tower_launched_jobs.type equals ad hoc

Ansible Tower Get Job Results

ansible_tower_launched_jobs

ansible_tower_get_job_results

ansible_tower_launched_jobs.type equals template

Ansible Tower List Job Templates

incident

ansible_tower_list_job_templates

-

Ansible Tower List Jobs

incident

ansible_tower_list_jobs

-

Ansible Tower Run an Ad Hoc Command

incident

ansible_tower_run_an_ad_hoc_command

-

Ansible Tower Run Job

ansible_tower_job_templates

ansible_tower_launch_job_template

ansible_tower_job_templates.template_id has_a_value

Ansible Tower Run Job - Artifact

artifact

ansible_tower_run_job__artifact

-

Ansible Tower Run Job - Incident

incident

ansible_tower_run_job__incident

-

+
+
+

Troubleshooting & Support

+

Refer to the documentation listed in the Requirements section for troubleshooting information.

+
+

For Support

+

This is a IBM Community provided app. Please search the Community ibm.biz/soarsupport for assistance.

+
+