Jenkins : Ansible Tower Plugin

Plugin Information

View Ansible Tower on the plugin site for more information.

Older versions of this plugin may not be safe to use. Please review the following warnings before using an older version:


This plugin connects Jenkins to Ansible Tower, allowing you to execute job templates.

Configuration

After installing the plugin you can configure Ansible Tower servers in the Jenkins Global Configuration under the section Ansible Tower by clicking the add button.


The fields are as follows:

Field NameDescription
NameThe name that this Ansible Tower installation will be referenced as.
URLThe base URL of the Ansible Tower server.
Credentials

The credentials within Jenkins to be used to connect to the Ansible Tower server.

  • For basic auth use a "Username with password" type credential
  • For oAuth (starting in Tower 3.3.0) use a "Secret Text" type credential from the Plain Credentials Plugin
    S
    ee the OAuth Authentication section of this document for more details on setting up oAuth.
Force Trust Cert

If your Ansible Tower instance is using an https cert that Jenkins does not trust, and you want the plugin to trust the cert anyway, you can click this box.

You should really understand the implications if you are going to use this option. Its meant for testing purposes only.


Enable Debugging

This will allow the plugin to write detailed messages into the jenkins.log for debugging purposes. It will show show requests to the server and payloads. This can contain a lot of data. All messages are prefixed with \[Ansible-Tower\].

For Example:

[Ansible-Tower] building request to https://192.168.56.101/api/v1/workflow_jobs/200/workflow_nodes/
[Ansible-Tower] Adding auth for admin
[Ansible-Tower] Forcing cert trust
[Ansible-Tower] {"count":4,"next":null ...

Once the settings are completed, you can test the connection between Jenkins and Ansible Tower by clicking on the Test Connection button.


Adding a Build Step

In a freestyle project a new build step called Ansible Tower is now available:

FieldDescription
Tower ServerThe predefined Ansible Tower server to run the template on.
Template TypeWhether you are running a job or workflow template.
Template IDThe name or numerical ID of the template to be run on the Ansible Tower server.
Extra Vars

Additional variables to be passed to the job. I.e.:
---
my_var: This is a variable called my_var 

Job Tags

Any job tags to be passed to Ansible Tower.

Skip Job TagsAny skip tags to be passed to Ansible Tower.
Job TypeIs this a template run or a check.
LimitThe servers to limit the invocation to.
InventoryThe name or numeric ID of the inventory to run the job on.
CredentialThe name or numeric ID of the credentials to run the job with.
VerboseAdd additional messages to the Jenkins console about the job run.
Import Tower OutputPull all of the logs from Ansible Tower into the Jenkins console.
Import Workflow Child OutputPull in the output from all of the jobs that the template runs.
Remove ColorWhen importing the Ansible Tower output, strip off the ansi color codings.

Pipeline support

Tower jobs can be executed from workflow scripts.
The towerServer and jobTemplate are the only required parameters.

Pipeline Example
node {
    stage('MyStage') {
        ansibleTower(
            towerServer: 'Prod Tower',
            templateType: 'job',
            jobTemplate: 'Simple Test',
            importTowerLogs: true,
            inventory: 'Demo Inventory',
            jobTags: '',
			skipJobTags: '',
            limit: '',
            removeColor: false,
            verbose: true,
            credential: '',
            extraVars: '''---
my_var:  "Jenkins Test"''',
            async: false
        )
    }
}

Async Execution

As of version 0.10.0, pipeline scripts have the async option. This will run the Tower job but immediately return the control of the job back to Jenkins. In the return value from ansibleTower will be an object that can be used later on to interact with the job:

Async Example
stage('Launch Tower job') {
    node('master') {
        // Here we launching the Tower job in async mode
        tower_job = ansibleTower(
                async: true,
                jobTemplate: 'Jenkins Export Vars',
                templateType: 'job',
                towerServer: 'Tower 3.6.0'
        )
        println("Tower job "+ tower_job.get("JOB_ID") +" was submitted. Job URL is: "+ tower_job.get("JOB_URL"))
    }
}

// Since control is returned this stage will run right away
stage('Something else') {
    node('master') {
        println("Doing something else")
    }
}

// Now we can use our tower_job object to wait for the Tower job to complete
stage('Wait for Tower job') {
    node('master') {
        def job = tower_job.get("job", null)
        if(job == null) {
            errir("The tower job was defined as null!")
        }
        timeout(120) {
            waitUntil {
                return job.isComplete()
            }
        }
    }
}

// Once the job is done we may want to do things like:
//    * Get the logs
//    * Check on exported values
//    * See if the job was successful or not
stage('Process Tower results') {
    node('master') {
        // Def a variable to save some typing
        def job = tower_job.get("job", null)
        if(job == null) {
            error("Tower job was null")
        }

        // First lets get and display the logs
  	    def Vector<String> logs = job.getLogs()
        for (String line : logs) {
            println(line)
        }

        // Now lets get our exports, these depend on us calling getLogs
        def HashMap<String, String> exports = job.getExports()
        def returned_value = exports.get("value", "Not Defined")
        if(returned_value != "T-REX") {
            println("Tower job did not return a T-Rex: "+ returned_value)
        } else {
            println("Exports were as expected")
        }

        // Finally, lets see if the job was successful
        boolean successful = job.wasSuccessful()
        if(successful) {
            println("Job ran successfully")
        } else {
            error("The job did not end well")
        }
    }
}

Note: the above example would require in-process script approvals in order to be run. Specifically the following needed to be added:

method java.util.Dictionary get java.lang.Object
method org.jenkinsci.plugins.ansible_tower.util.TowerJob getExports
method org.jenkinsci.plugins.ansible_tower.util.TowerJob getLogs
method org.jenkinsci.plugins.ansible_tower.util.TowerJob isComplete
method org.jenkinsci.plugins.ansible_tower.util.TowerJob wasSuccessful
new java.util.HashMap
new java.util.Vector

Please consider if you want these options added and use at your own risk.

Expanding Env Vars

The fields passed to Tower (jobTemplate, extraVars, limit, jobTags, inventory, credential) can have Jenkins Env Vars placed inside of them and expanded. For example, if you had a job parameter as TAG you could expand that in the Extra Vars like this:

---
my_var: "$TAG"

Console Color

You need to install another plugin like [AnsiColor plugin](https://wiki.jenkins-ci.org/display/JENKINS/AnsiColor+Plugin) to output a colorized Ansible log.

Pipeline Example With AnsiColor
node {
	wrap([$class: 'AnsiColorBuildWrapper', colorMapName: "xterm"]) {
		ansibleTower(
			towerServer: 'Prod Tower',
			jobTemplate: 'Simple Test',
			importTowerLogs: true,
			inventory: 'Demo Inventory',
			jobTags: '',
			limit: '',
			removeColor: false,
			verbose: true,
			credential: '',
			extraVars: '''---
			my_var: "Jenkins Test"'''
		)
	}
}

If you do not have a plugin like AnsiColor or want to remove the color from the log set removeColor: true.

OAuth Authentication

Starting in Tower version 3.3.0, Oauth Authentication can be used alongside basic auth. Beginning in Tower version 3.4.0, basic authentication will be disabled.

The Ansible Tower Documentation covers this in detail, but here is a rough outline of what needs to be performed.

Tower Configuration

  1. Add an Application for the Jenkins Oauth tokens
    1. Name (i.e. "Jenkins")
    2. Description (optional)
    3. Organization (The organization which covers the JTs and WFJTs you will be using)
    4. Authorization Grant Type = Resource owner password-based
    5. Client Type = Confidential
  2. Add or create a user to bind to an Oauth token
    1. This should be a service account with limited permissions.
    2. Add a Token for this user with the Users / <Username> / Tokens / Create Token dialogue (with the appropriate scope)
    3. Copy the Token ID which is generated on the prompt.

Jenkins Configuration

  1. Install this plugin (it must be a version >= 0.90)
  2. Add a Credential
    1. Choose the appropriate scope
    2. Secret = Token ID from step 2.c above
    3. ID = Something to denote it's purpose (i.e. "jenkins-tower-token")
    4. Description (optional)
  3. Complete the configuration steps as defined in this guide's 'Configuration'

Returning Data

The plugin supports sending data from Tower back to Jenkins for use in your job. There are two method for exporting data: Purpose Driven Logging and Setting Stats

Purpose Driven Logging

Then, in your Tower job simply include a debugging statement like:

    - name: Set a Jenkins variable
  debug:
msg: "JENKINS_EXPORT VAR_NAME=value"
 

The Tower plugin will recognize this message and use EnvInject plugin to add an environment variable named VAR_NAME with a value of "value" into the pipeline for consumption by downstream tasks.

Setting Stats

Another option is to use the set_stats module in Ansible like:

    - name: Set a jenkins variable for with stat
      set_stats:
        data:
          JENKINS_EXPORT:
            - some_name: var_value
            - some_other_var : Another value
        aggregate: yes
        per_host: no

The Tower plugin will look for variables under JENKINS_EXPORT and use EnvInject plugin to add an environment variables into the pipeline for consumption by downstream tasks. In the previous example two variables would be created: some_name, set to var_value; and some_other_var set to "Another value".

Please reference set_stats documentation for usage and additional parameters, per_host and aggregate are not necessarily needed.


The process to leverage the returned data in Jenkins depends on your job type:

Freestyle returns

The plugin supports sending data back to Jenkins as environment variables via the EnvInject plugin. First be sure the plugin is installed (its not a dependency for this plugin, it needs to be installed separately).

If you try to export a variable but don't have the EnvInject plugin installed the Tower plugin will let you know with a message like:

    Found environment variables to inject but the EnvInject plugin was not found

Pipeline returns

When running under a pipeline, the EnvInject plugin is not required. The environment variables will either be:

  • Returned in the return object (for non-async jobs)
  • Accessible through the job object (for async jobs)

The async job example can be seen above in the Pipeline Support section.

For a non-async job you can access the variables as so:

Variable Extraction
node {
    stage ('deploy gitlab') {
        wrap([$class: 'AnsiColorBuildWrapper', colorMapName: "xterm"]) {
            results = ansibleTower(
                towerServer: 'Tower 3.3.0',
                jobTemplate: 'Jenkins Export Vars',
                importTowerLogs: true,
                removeColor: false,
                verbose: true,
            )
            
            sh 'env'
        }
        println(results.JOB_ID)
        println(results.value)
    }
}

There are three special variables in results: 

  • JOB_ID - a string containing the Tower ID number of the job
  • JOB_URL - a string containing the URL to the job in Tower
  • JOB_RESULT - a String of either SUCCESS or FAILED depending on the job status.
    Note: This variable is only applied for a non-async job.


Open Issues

Key Summary T Created Updated Due Assignee Reporter P Status Resolution
JENKINS-65013 Ansible Tower Plugin - Have access to User credentials Bug Mar 04, 2021 May 05, 2021 John Westcott sébastien Minor Open Unresolved
JENKINS-63369 ansible plugin - importTowerLogs Bug Aug 10, 2020 Aug 11, 2020 Jean-Christophe Sirot Jose Flores Major Open Unresolved
JENKINS-63142 Sliced job template in workflow causes jenkins pipeline failure Bug Jul 20, 2020 Jul 20, 2020 John Westcott Don Kallman Minor Open Unresolved
JENKINS-62838 Ansible Tower Project Sync does not override Credentials in freestyle Job Bug Jun 27, 2020 Jun 30, 2020 John Westcott Sebastian Oss Major Open Unresolved
JENKINS-62525 Add some reconnection mechanism to Ansible Tower job monitoring Improvement Jun 01, 2020 May 11, 2021 John Westcott Adam Medziński Major Open Unresolved
JENKINS-62428 Unable to use an env. variable for SCM_BRANCH configuration Bug May 25, 2020 Jul 03, 2020 John Westcott Georg Koch Major Open Unresolved
JENKINS-55247 Make Ansible Tower Plugin import the output from a sliced job template Improvement Dec 18, 2018 Jul 20, 2020 John Westcott Elyézer Rezende Minor Open Unresolved
JENKINS-55246 Add credential button is not working on Ansible Tower Plugin configuration Bug Dec 18, 2018 Aug 19, 2019 Elyézer Rezende Elyézer Rezende Minor Open Unresolved
JENKINS-54366 Ansible tower 3.3 with plugins 0.9 have issue in workflow extra variables passing Bug Oct 31, 2018 Dec 06, 2018 John Westcott cap ho Minor Reopened Unresolved
JENKINS-50370 Return Ansible Tower STDERR only Improvement Mar 23, 2018 Mar 26, 2018 m t m t Minor In Review Unresolved
Authenticate to retrieve your issues


Changelog

Version 0.10.0 (Oct-13-2019)

  • Canceling a job in Jenkins will now attempt to cancel the job in Tower as well.
  • Requirements in pom.xml are now pulled over https. Thanks to Daniel Beck for the Pull Request.

Version 0.10.0 (Aug-14-2019)

  • Returned values can now be accessed in a pipeline.
  • Pipelines can now run jobs asynchronous.

Version 0.9.2 (Apr-30-2019)

Version 0.9.1 (Dec-02-2018)

My apologies for the delay in getting this fix out. One of the things which took a while to setup was a more robust testing environment. Hopefully issues like the login issues with the last release will be able to be caught before they are released. Thanks the community for all of the help with the following fixes as well as to the Ansible Tower Engineering team for working with me on a better way to achieve the task at hand.

  • Fixing authentication issues. We initially were trying to determine the version number of Tower/AWX and then make a decision on authentication method. We now do it like tower-cli does by checking for /api/v2/o to determine if we need to authenticate with an oAuth token or a legacy token type. Thanks to Lukas Tischler for the Pull Request starting this fix.
  • In addition, we added more logging message when a Tower instance is set to debug as to what is happening with authentication.
  • Fixed some typos in log messages.
  • Fixed issue if you have Force Trust cert enabled but you are connecting to an AWX instance on http.
  • The plugin now attempts to give you more details if it receives a 403 (Unauthorized) from the instance.
  • Fixed an issue where newer versions of Tower failed if credentials were not in integer format. Thanks to James McShane for the Pull Request. [ JENKINS-54503 ]
  • The plugin now returns JOB_ID, JOB_URL and JOB_RESULT back to Jenkins. Thanks to Lukas Tischler for the Pull Request.
  • The plugin can now be configured to not fail a job if a Tower execution fails. Thanks to Lukas Tischler for the Pull Request.

Version 0.9.0 (Sep-25-2018)

  • Added support for oAuth to Tower.
  • Fixed connection issues with Tower 3.3.0 using Basic Auth.

Version 0.8.7 (Jul-23-2018)

  • Fixed URI to authtoken.

Version 0.8.6 (Jul-15-2018)

Version 0.8.5 (Jun-03-2018)

  • Decreased version dependency on EnvInject plugin due to issues. Thanks to Mikael Gaunin for the Pull Request.

Version 0.8.4 (Apr-29-2018)

  • Removed comparable since in pom.xml to prevent warning about invalid config files. [ JENKINS-51009 ] Thanks to Adrien for catching this.

Version 0.8.3 (Apr-13-2018)

Version 0.8.2 (Mar-24-2018)

  • Added help text for template ID. [ JENKINS-50239 ]
  • Notes for extra vars, job tags, limit, inventory and credential now indicate that "Prompt on Launch" in the template is required for the setting to take affect in Tower [ JENKINS-49915 ]

Version 0.8.1 (Mar-10-2018)

  • The connection will now be attempted by an authtoken first, if that fails (like on the new versions of AWX) it will revert to Basic Auth. [ JENKINS-50031 ]

Version 0.8.0 (Feb-18-2018)

  • Mostly changes when interacting with Tower:
    • Added filtered lookups of items by name to reduce time searching through the results and also prevent pagination issues.
    • Plugin now utilizes authtokens after initial login. This should decrease run times when the Tower instance is using an external authenticator (such as LDAP).
    • Changes to the logging to try and prevent pagination issues and also enhance the speed of looking up logs.
  • Contributed code enhancements:
    • Source code spelling fixes. (Josh Soref)
    • Fixes for warning if passing items (such as credentials) but the job template is not prompting for the item. (Josh Offutt)
    • Final check for log entries after the job completes running. (James McShane)

Version 0.7.0 (Jan-02-2018)

  • Fixed an issue with purpose driven logging where ending color codes could have been included in variable values
  • Added debugging option to Tower configuration
  • Added set_stats variable detection for variable export

Version 0.6.1 (Dec-20-2017)

  • Bug fixes for last release (it basically didn't work)
  • Added some checking for passed credentials and inventory (even if an ID is passed)
  • Also tries to give a better error if extra vars are bad

Version 0.6.0 (Dec-12-2017)

  • Allowed returning variables back to Jenkins via logging

Version 0.5.4 (Dec-7-2017)

  • Plugin now reports if you are passing in a value (like job tags) but prompt on launch is not configured for the job template. [ JENKINS-48377 ]
  • Workflows with inventory updates or sum updates no longer fail when pulling logs back into Jenkins. [ JENKINS-48438 ]

Version 0.5.3 (Dec-2-2017)

  • Fixed bug where existing jobs would get NullPointerExceptions when installing the new version of the plugin.

Version 0.5.2 (Dec-2-2017)

  • Added option to specify workflow or job templates
    Thanks again to Alvin Wong for the suggestion. 

Version 0.5.1 (Nov-21-2017)

  • Expanded Jenkins EnvVars in all fields being passed to Tower
    Thanks to Alvin Wong for the suggestion.

Version 0.5.0 (Nov-11-2017)

  • Initial release



Attachments: