Dealing with a password with special characters in Ansible
Solution 1
Probably a little late but the exact solution to your specific problem is:
ansible-playbook test-playbook.yml -i hosts -u daniel --extra-vars ansible_ssh_pass=$'"u5!vuL!<35Lf?<>n\'x"'
The shell treats $'<string>'
specially and escapes the single quote inside (see the backslash)
The outermost double quotes are necessary so that jinja2 template engine does not get confused inside ansible.
That being said, it is quite a bad idea to run the command like this for at least two reasons:
- It's not secure. Anyone with access to listing processes on the machine or to your shell history will be able to see the password.
- It's not flexible. Ansible extra variables provided on the command line have the highest precedence. If you add an other host in your inventory with a different ssh password, you won't be able to differentiate the two passwords.
For the first problem, and if you are sure you will only have one machine (or the same password everywhere), you could ask for the password interactively with vars_prompt for example (http://docs.ansible.com/ansible/latest/user_guide/playbooks_prompts.html)
The best approach solving both issues is to add the password using vault encryption to your inventory for the particular host. You then provide the overall vault password interactively (--ask-vault-pass) or through a well secured vault password file (--vault-password-file=) when you call the playbook.
Solution 2
Finally figured this one out for a password changing script that couldn't use vars_prompts.
For my bash
program that was running ansible
I needed to first get the password from a user via read
then do the following:
- Convert the bad string into
base64
and save tob64_pass
- Pass
b64_pass
asb64_ansible_ssh_pass
extra arg - Use
set_fact
to setansible_ssh_pass
and useb64decode
filter on extra argb64_ansible_ssh_pass
Short example testba.sh:
#!/bin/bash
read -p -s "Enter ssh password: " ssh_pass
# Convert input or var to base64
b64_pass=$(printf '%s' "$ssh_pass" | base64)
# Run ansible command
ansible-playbook test.yml -m shell -a "echo OK" -e "b64_ansible_ssh_pass='$b64_pass'" -v
Playbook test.yml:
- hosts: all
# Assign ansible_ssh_pass in vars OR below in task with set_fact
vars:
ansible_ssh_pass: "{{ b64_ansible_ssh_pass | b64decode }}"
tasks:
# Assign ansible_ssh_pass in task with set_fact
- name: Set ssh pass
set_fact:
ansible_ssh_pass: "{{ b64_ansible_ssh_pass | b64decode }}"
no_log: true
- shell: echo hi
If you need to pass a password var into the user module
#!/bin/bash
read -p -s "Enter ssh password: " ssh_pass
# Convert input or var to base64
b64_pass=$(printf '%s' "$ssh_pass" | base64)
# Run ansible command
ansible <hosts_to_run_on> -m shell -a "echo OK" -e "new_pass=$b64_pass"
Then in your playbook
- hosts: all
vars:
my_new_pass: "{{ new_pass | b64decode }}"
tasks:
user:
name: "NewUser"
password: "{{ my_new_pass }}"
radicaled
Updated on July 11, 2022Comments
-
radicaled almost 2 years
I'm trying to run an ansible playbook with the ansible_ssh_pass option to connect to the destination server.
ansible-playbook test-playbook.yml -i hosts -u daniel --extra-vars "{"ansible_ssh_pass":"u5!vuL!<35Lf?<>n'x"}"
The problem is that the password has special characters. I tried saving it using.
"password\'s" "password" "\"password\""
Any idea how can I save the password?
-
tweeks200 over 6 yearsIf your using linux you could setup and ssh key for the user you want and bypass the password altogether
-
radicaled over 6 yearsWe are not allowed to share keys between the server. The idea is to do the connection using user/pass.