On previous posts we’ve seen how to connect with Ansible using credentials stored in a inventory file, and using SSH keys for authentication.
However, it isn’t a good idea to store credentials in plain text files, neither have to rebuild your inventory when you want to switch over to key authentication.
A possible solution is to first ask for credentials, run a playbook to install the SSH key, and then use this key for authentication on later playbooks.
You can find all the files for this post on the following repo.
https://github.com/baldoarturo/ansible-ssh-keys
Variable prompts
vars_prompt:
- name: "ansible_user"
prompt: "Username"
private: no
The vars_prompt section is used to prompt the user for information, which is stored in variables. System variables can be populated, for example the ansible_user and ansible_password variables, allowing us to provide credentials to connect.
Take a look to the new version of the uptime playbook.
---
- hosts: all
gather_facts: no
vars_prompt:
- name: "ansible_user"
prompt: "Username"
private: no
unsafe: yes
- name: "ansible_password"
prompt: "Password"
private: yes
unsafe: yes
tasks:
- name: Get uptime
junos_command:
commands:
- show system uptime
register: uptime
- name: Show uptime
debug: var=uptime
We’re prompting for the username and password on the vars_prompt section. The private settings indicates if the user input should appear on the screen. The unsafe option allows to enter special chars.
The task to execute are:
- Get system uptime via the junos_command module, with “show system uptime”
- Print the result using debug
And the new (and definitive) inventory looks like this now.
all:
hosts:
"192.168.227.101":
vars:
ansible_connection: netconf
ansible_network_os: junos
ansible_ssh_private_key_file: juniper-hosts.key
ansible_python_interpreter: auto_silent
The ansible_python_interpreter variable is set to auto_silent just to avoid the warning about no Python interpreters on the remote end.
Let’s give the playbook a run, trying to login with user and password. If you have not been following the Ansible series, let me tell you that there is an user admin with a password of Password$1 on the router. Note that the password won’t be seen on the screen.
arturo@arturo-ThinkPad-L440:~/Desktop/ansible-01$ ansible-playbook junos-auth-with-key.yaml -i junos-hosts.yaml
Username: admin
Password:
PLAY [all] ******************************************************************************************************************
TASK [Get uptime] ***********************************************************************************************************
ok: [192.168.227.101]
TASK [Show uptime] **********************************************************************************************************
ok: [192.168.227.101] => {
"uptime": {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"failed": false,
"stdout": [
"Current time: 2020-01-13 17:12:32 UTC\nSystem booted: 2020-01-13 14:55:46 UTC (02:16:46 ago)\nProtocols started: 2020-01-13 14:56:03 UTC (02:16:29 ago)\nLast configured: 2020-01-12 16:09:02 UTC (1d 01:03 ago) by admin\n 5:12PM up 2:17, 2 users, load averages: 0.00, 0.00, 0.00"
],
"stdout_lines": [
[
"Current time: 2020-01-13 17:12:32 UTC",
"System booted: 2020-01-13 14:55:46 UTC (02:16:46 ago)",
"Protocols started: 2020-01-13 14:56:03 UTC (02:16:29 ago)",
"Last configured: 2020-01-12 16:09:02 UTC (1d 01:03 ago) by admin",
" 5:12PM up 2:17, 2 users, load averages: 0.00, 0.00, 0.00"
]
]
}
}
PLAY RECAP ******************************************************************************************************************
192.168.227.101 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Great, the prompts work.
What if we try to login with the user ansible we configured on the previous post? This user has an SSH key installed on the router, and the local private key is on juniper-hosts.key.
arturo@arturo-ThinkPad-L440:~/Desktop/ansible-01$ ansible-playbook junos-auth-with-key.yaml -i junos-hosts.yaml
Username: ansible
Password:
PLAY [all] ******************************************************************************************************************
TASK [Get uptime] ***********************************************************************************************************
ok: [192.168.227.101]
TASK [Show uptime] **********************************************************************************************************
ok: [192.168.227.101] => {
"uptime": {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"failed": false,
"stdout": [
"Current time: 2020-01-13 17:32:05 UTC\nSystem booted: 2020-01-13 14:55:46 UTC (02:36:19 ago)\nProtocols started:
2020-01-13 14:56:03 UTC (02:36:02 ago)\nLast configured: 2020-01-12 16:09:02 UTC (1d 01:23 ago) by admin\n 5:32PM up 2:36,
1 user, load averages: 0.00, 0.01, 0.00"
],
"stdout_lines": [
[
"Current time: 2020-01-13 17:32:05 UTC",
"System booted: 2020-01-13 14:55:46 UTC (02:36:19 ago)",
"Protocols started: 2020-01-13 14:56:03 UTC (02:36:02 ago)",
"Last configured: 2020-01-12 16:09:02 UTC (1d 01:23 ago) by admin",
" 5:32PM up 2:36, 1 user, load averages: 0.00, 0.01, 0.00"
]
]
}
}
PLAY RECAP ******************************************************************************************************************
192.168.227.101 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Excellent, by using the user ansible without password, it will fallback to the key authentication.