Let’s assume you want to access a monitoring host from an Ansible play which is launched by Ansible Tower/AWX, and let’s further assume that you require credentials with which to do so. The trivial demonstration play will be this one:

- name: Zshow me your variables
  hosts: all
  - name: Which is the zurl?
    debug: msg="it is {{ zurl }}"

  - name: And the password?
    debug: msg="the secret is {{ zpass }}"

You could well use Ansible’s extra_vars with which to do so, something along the lines of

zurl: http://zabbix.example.net/zabbix
zuser: zabbix
zpass: password

This means, though, that whoever can access the Tower/AWX job template description will see the values (in particular the password) in clear text. Furthermore, logs, of job template runs will also show them, and you really don’t want that to happen, do you? You don’t!

extra vars are visible at any time in job logs

Ansible Tower/AWX have somthing I particularly enjoy (and I spend some time explaining it in the trainings I give): it’s called “custom credential types”.

I can create a new “type” of credential, which AWX/Tower presents to the user as though it were built-in. Furthermore, AWX/Tower secure the data therein by encrypting fields marked secret into the backend database, just like they do for other types of credentials such as machine or AWS credentials.

I first create a new type by defining the fields it will have and how these will be passed to my playbook. The former is called input configuration and the latter injector configuration.


Both these configurations are specified as YAML or as JSON, and ought to be pretty self-explanatory; note the secret attribute on my zpass field which ensures its value cannot be seen on data entry or later, when the credential is opened.

- id: zurl
  type: string
  label: Zurl
- id: zuser
  type: string
  label: Zusername
- id: zpass
  type: string
  secret: true
  label: Zpassword
- zpass
- zuser
- zurl

There’s also a multiple choice field which can be quite practical, though it cannot be fed from a URL, unfortunately. (But thanks to the AWX API, we can pump data into that field from outside; I digress.)

The injector configuration defines how these variables should be passed to our Play. We can use extra vars as I’ve shown, but AWX/Tower can also create INI files for us and drop those in a temporary location on the controller. I find extra vars easier to handle (and to explain) and they should suffice for most use-cases.

As soon as the credential type is defined, I can go ahead and create a credential of that type:

I create a credential of our new type

Now that I have a credential with the data we want in it, I can assign that to our job template, and I do that just like assigning any other credential type:

assign credential to job template

When I now launch my job template (note that there are no extra_vars in the template definition), the play runs as I want it to:

the play runs

Tower/AWX takes particular care of these values: they don’t appear in logs (unless I’m careless enough to provoke that as in this example where I output the values), and they cannot be overwritten, so if I erroneously create an extra var called zurl, say, AWX will not clobber the one from the credential type. (I would try to apply naming conventions so that that can’t happen by mistake, though.)

I used Zabbix in this example for two reasons: first of all I use it myself (did I tell you I intend to give a talk about Zabbix loadable C modules at the upcoming LOADays conference?), and then because I recently stumbled across a similar example on a Red Hat site which upset me because it showed credentials in extra variables; that should be a no-no.

ansible, credentials, and awx :: 16 Apr 2019 :: e-mail