Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

My new server instances are configured to login on root via ssh with password. I want my playbook to reconfigure it to use keys instead and disable root login with password on first run, so I need something like this:

  • try to login with key
  • if can't login with key:

    • login with password
    • add key to authorized_keys
    • disable root login with password
    • optionally reconnect using key
  • do other tasks

How can I acomplish that?

EDIT: To be clear, I'm not asking how to add key or disable root, that's just for context. I'm asking how to fallback to password if couldn't authenticate with key. With --ask-pass or ansible_ssh_pass set, ansible won't even try to use public key authentication

share|improve this question
Good question, what have you tried so far? – dawud Nov 4 '13 at 18:08
I took the ssh configuration to a separate playbook and I run it with -k option, then I run the main playbook without -k (using key from agent). I was hoping it can be wrapped in a single playbook though... – petr0 Nov 4 '13 at 18:26
up vote 2 down vote accepted

You could try the PreferredAuthentications option, setting it to publickey,password. The default includes these in this order, along with other options, so ansible is presumably setting this. Adding it via -o or the client ssh_config may prevent this.

You may be able to use a wrapper script. For example, with this in and a that gives the password, running bash root@host will try a publickey followed by a non-interactive password login.

export DISPLAY=dummy:0
exec setsid ssh -v -o 'PreferredAuthentications publickey,password' "$@"

The log indicates which method succeeded with, e.g.

debug1: Authentication succeeded (publickey).
share|improve this answer

Because I dont yet have reputation for comments, i need to write it as answer but it might not be complete. You can use --ask-pass when running ansible-playbook.

For other tasks you asked, it is achievable by various means, eg, copy module. Disabling root login also can be done eg. by templating sshd_conf or inserting line in conf file.

share|improve this answer
--ask-pass (which is the same as -k) is what I'm doing and I wrote about it in the comment above – petr0 May 17 '14 at 10:35

Here's what I do if ansible_user is different for the 'first run' of the playbook (for example if you only have a root user and you're going to set up a new user with an SSH key):

  • Store the password in ansible_pass as you would if you were using password logins (remember to use Vault) this should be the password of the user you're using for the 'first run' of the playbook.
  • Set ansible_user to the username of the user you wish to use after the first run when you have users set up correctly on the server.
  • Set a variable of ansible_user_first_run to the user you're going to use for the 'first run' of the playbook, for example root.
  • Use a local command to attempt to connect to the server with the correct SSH key, using ignore_errors and changed_when: False
  • If that fails, update ansible_user to the value of ansible_user_first_run

Here's the code:

- name: Check if connection is possible
  command: ssh -o User={{ ansible_user }} -o ConnectTimeout=10 -o PreferredAuthentications=publickey -o PubkeyAuthentication=yes {{ inventory_hostname }} echo "Worked"
  register: result
  connection: local
  ignore_errors: yes
  changed_when: False
- name: If no connection, change user_name
  connection: local
    ansible_user: "{{ ansible_user_first_run }}"
  when: result|failed

Note: It's worth setting up transport = ssh as paramiko can unexpectedly fail to login to the server in some configurations (e.g. when the server is set up not to accept passwords, and you're trying first with a key then a password... weird!) Also ssh transport is faster, so it's worth it anyway.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.