How to use Credentials in AWX playbook

Hi All,

I am just new on the AWX and ansible. How do i tell the playbook to use the credentials on a playbook that is going to be run via AWX?. I create the credentials via AWX GUI for Network in my case. What variable or values i need to pass it on the playbook so that AWX will grab it properly to use it?.

currently my playbook is like this on ansible.

Suresh,

Add survey option is there to provide the run time variables.
instead of calling from another yml.

Maybe i should re-word my question,

How i can modify the above playbook so that vault/credentials can be accessed/invoked/used in the playbook via template?.

S.Suresh

This is a great question… I’m having exactly the same issue and I’m struggling to get information about this.

How can I reference a Credential I’ve set up in AWX.

If my playbook looks like this (See below), how can I tell Ansible to look for the Private key and the username created in the AWX-Credentials area?

Hi all,

Credentials are injected in the running Ansible environment in 3 ways:

  1. env variables
  2. ansible extra variables
  3. files (usually with an env variable pointing at the file path)

Suresh,

Your using network credentials. These are injected via ENV variables. Specifically:

`
for network_cred in job.network_credentials:
env[‘ANSIBLE_NET_USERNAME’] = network_cred.username
env[‘ANSIBLE_NET_PASSWORD’] = decrypt_field(network_cred, ‘password’)

ssh_keyfile = cred_files.get(network_cred, ‘’)
if ssh_keyfile:
env[‘ANSIBLE_NET_SSH_KEYFILE’] = ssh_keyfile

authorize = network_cred.authorize
env[‘ANSIBLE_NET_AUTHORIZE’] = six.text_type(int(authorize))
if authorize:
env[‘ANSIBLE_NET_AUTH_PASS’] = decrypt_field(network_cred, ‘authorize_password’)
`

In Ansible, you use a lookup to get environment variables. ie. lookup(‘env’,‘ANSIBLE_NET_USERNAME’)

Daniel,

Looks like you want:

Hi Chris,

Thanks for your clear answer. Based on it, I could see I wasn’t using a Network-type credential but machine-type credentials instead. I’ve now changed my credential to this and I can see some content in the ANSIBLE_NET_SSH_KEYFILE

However, I’m still unable to access my devices. As the content of the ssh file is encrypted, is it expected to see the following:?
SSH Key file content

`
TASK [Show the content of the SSH Key] *****************************************
ok: [man3-rc-core4500-01] => {
“msg”: “/tmp/awx_77_dZzrdo/tmpli6mRb”

`

In an ideal scenario, shouldn’t I see something like this: instead ?

`
msg: -----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED …

`

I’m struggling as I cannot see what I’m passing to my network devices as a credential.
Error

`
TASK [Retrieving full config from devices] *************************************
e30=DeyJ1dWlkIjogIjJiZDMzZmE0LTMxZjItNDMwZi1iMDExLTE5NWU0MGNkM2Q5OCJ9Dfatal: [man3-rc-voip4200-04]: FAILED! => {“changed”: false, “msg”: “Unable to make a PyEZ connection: ConnectAuthError(man3-rc-core4500-01)”}

`

Next, you can see the playbook I’m using. I’ve got 2 tasks:
Task 1- To debug the content of the ANSIBLE_NET_SSH_KEYFILE that I’m using to pass to my devices on the 2 task
Task 2 - Pass the credentials to my network devices.

Pbook

`

  • name: Show the content of the SSH Key
    debug:
    msg: ‘{{ lookup(“env”, “ANSIBLE_NET_SSH_KEYFILE”) }}’
    ^^ will not show the contents of the file, it will just print the file location.

{{ lookup(“file”, “ANSIBLE_NET_SSH_KEYFILE” }} ← will print the contents of the file.

I’m not super familiar with network modules. Might you need to tell the networking modules to accept ssh host keys?

Thanks Chris,

As per the Juniper network module documentation I’m using, the default behavior for this module is to look for the path this way:

The first defined value from the following list

  1. The ANSIBLE_NET_SSH_KEYFILE environment variable. (used by Ansible Tower)
  2. The value specified using the --private-key or --key-file command line arguments to the ansibleor ansible-playbook command.
  3. none (the file specified in the user’s SSH configuration, or the operating-system-specific default)

If that’s the case then AWX is passing the following path to the module:
/tmp/awx_77_dZzrdo/tmpli6mRb

Which as I understand would be the location of the network-type credential (encrypted). Should then the module be able to decrypt the file by itself?.

Based on your suggestion I’ve modified my playbook to output the content of the file

`

  • name: Show the content of the SSH Key
    debug:
    msg: ‘{{ lookup(“file”, “ANSIBLE_NET_SSH_KEYFILE”) }}’
    `

When I re-run the Job in AWX I get back the following:

`
TASK [Show the content of the SSH Key] *****************************************
[WARNING]: Unable to find ‘ANSIBLE_NET_SSH_KEYFILE’ in expected paths (use
-vvvvv to see paths)

fatal: [man3-rc-core4500-01]: FAILED! => {“msg”: “An unhandled exception occurred while running the lookup plugin ‘file’. Error was a <class ‘ansible.errors.AnsibleError’>, original message: could not locate file in lookup: ANSIBLE_NET_SSH_KEYFILE”}
[WARNING]: Unable to find ‘ANSIBLE_NET_SSH_KEYFILE’ in expected paths (use
-vvvvv to see paths)
`

What I’m trying to understand here is if this is expected from the AWX perspective or if this is something the 3rd party (Juniper) is failing to handle from its module?

Thanks once again for your help and for taking the time to answer this query.
Regards

My mistake, you need a lookup nested in your lookup. One lookup to get the filename, another lookup to read the file. i.e.

{{ lookup(“file”, lookup(“env”, “ANSIBLE_NET_SSH_KEYFILE”)) }}

Ohh no probs Chris,

The minute I posted my reply I realised that what you’re saying about reading the path first and then the content. I have restructured my playbook now to achieve it, read the path and then the content.

What I can see in stdout is the content of the private key (as expected) but I’m a bit unsure of whether I should see the new lines \n. Is this expected? When I copy my private key to AWX, obviously there are some newlines \n (invisible) in it. Please have a look at the output of task 2.

Task 1 Output (The path that AWX is using to store my encrypted private key)

ok: [man2-rc-access4200-09a] => { "msg": "/tmp/awx_92_i0z9B7/tmpZvwup0"

Task2 Output (The content of my private key unencrypted - You can see the \n)
`
ok: [man2-rc-access4200-09a] => {
“msg”: “-----BEGIN RSA PRIVATE KEY-----\nProc-Type: 4,ENCRYPTED\nDEK-Info: AES-128-CBC,14\n\nPRIVATE_RANDOM_KEY_n/xZiB\n-----END RSA PRIVATE KEY-----”,

`

See the end of lines… \n → I’m not too sure if this is actually what gets passed to the network module. I guess it is but if that’s the case, would that be a problem?

Task 3 - Network Module Error

`
TASK [Retrieving full config from devices] *************************************
e30=DeyJ1dWlkIjogImFkNmU2YTM0LWVjNmMtNDY0My04OTYwLTQ1MDlhZTg5YjE5NSJ9Dfatal: [man3-rc-voip4200-02]: FAILED! => {“changed”: false, “msg”: “Unable to make a PyEZ connection: ConnectAuthError(man3-rc-voip4200-02)”}

`

Pbook

`

I couldn’t resist on trying now and it worked locally from the container. Not from AWX though but I’m getting really close :slight_smile:

From inside the AWX_TASK_1 container, I can see that key totally matches to what AWX is passing to the network module.

Now, the only difference that I can think of is that locally from the container I’m using the ansible-playbook -k option to pass my ssh_key passphrase to the network module. Is there any way to replicate this in AWX?

I’ve added my passphrase to the network-type credentials so it should be encrypted. However, I don’t know to what environment variable this gets mapped to.

Is there any way I can pass passphrase from AWX to the network module?. What would it be the environment variable I should user for this?

Just to be clear on what I’m thinking. Something like this

`

  • name: Retrieving full config from devices
    juniper_junos_config:
    host: ‘{{ inventory_hostname }}’
    user: ‘netscript’
    ssh_private_key_file: ‘{{ SSH_LOCATION }}’
    password**: ‘{{ ANSIBLE_NET_SSH_KEY_PASSPHRASE }}’**
    port: 830
    timeout: 300
    format: text
    return_output: false
    retrieve: committed
    dest_dir: ‘output/’
    tags:
  • get_conf

`

Thanks again.

Hi Chris,

I’d like to thank you for all your support. Really appreciated!!

I’ve managed to make it work now with the following pbook and credentials

`

  • name: NET - PULLING CONFIG
    hosts: OFFICES
    connection: local
    gather_facts: no
    roles:
  • Juniper.junos
    tasks:

COMMENTED WAS USED FOR DEBUGGING PURPOSES

- name: Show the path of the SSH Key passed from AWX

debug:

msg: ‘{{ SSH_LOCATION }}’

- name: Show the content of the SSH Key passed from AWX

debug:

msg: ‘{{ lookup(“file”, “{{ SSH_LOCATION }}”) }}’

- name: Show the content of the SSH Passphrase from AWX

debug:

msg: ‘{{ lookup(“env”, “ANSIBLE_NET_PASSWORD”) }}’

  • name: Retrieving full config from devices
    juniper_junos_config:
    host: ‘{{ inventory_hostname }}’
    user: ‘netscript’
    ssh_private_key_file: ‘{{ SSH_LOCATION }}’
    passwd: ‘{{ lookup(“env”, “ANSIBLE_NET_PASSWORD”) }}’
    port: 830
    timeout: 300
    format: text
    return_output: false
    retrieve: committed
    dest_dir: ‘output/’
    tags:
  • get_conf

`

As a side note. The ANSIBLE_NET_PASSWORD gets passed from the AWX “password” field on the Network-type credential (See picture attached). I would like to understand to where, the “private key passphrase” field gets mapped to.

How can I get information about the environment variables that AWX uses to map it’s credential fields?. Is there any documentation page that shows me what you’ve been telling me?

I’m leaving the information here hoping that some else comes across the same issue and can benefit of this loop.

Thanks and regards.

(attachments)

Daniel,

You found a bug. https://github.com/ansible/awx/issues/2150

Note that AWX fills in passwords for prompted ssh passwords for you it does NOT inject them for your use as an environment variable.

This should fix your problem. Can you verify it when it lands? https://github.com/ansible/awx/pull/2158

Hi Chris,

I’m out of the office today but I’ll give that a try on Monday to see if this works properly now.

I’ll update this post with my findings.

Thanks

Daniel,

Did you get a chance to test this? We’ve since released a new version of AWX that this fix is in.

Thanks,
-Chris

ping

Hi Chris,

Sorry, but I haven’t’ had much time lately to do any work for my AWX project. I’m now using the devel branch for the test and I can see your commit on the logs so I can see the fix is there.

Can you please guide me on the expected result or how can I test this fix?. I’ve been reading your fix and the build_password() function and as I understand, based on your comment the fix should prefer the ssh passphrase over the password?

Anyway, this is my current pbook

`

(attachments)



  • for testing, remove the following line:
    passwd: ‘{{ lookup(“env”, “ANSIBLE_NET_PASSWORD”) }}’
  • Do not set the password field in your Netscript credential
  • We now disallow jinja2 in extra_vars by default so don’t have the level of indirection i.e. remove SSH_LOCATION: ‘{{ lookup(…) }}’ and replace usages of SSH_LOCATION with ANSIBLE_NET_SSH_KEYFILE

Hi Chris,

The following are the results of my test:

I’ve modified my Pbook to the following:

`

(attachments)