Remote server setup "failed to connect to the host via ssh"

I’m trying to set provision a server on DO. Keys are set up (i~/.ssh/id_rsa.pub) , I can ping the host by name and ip, and ssh in as well from the terminal without a password. Message says the host is UNREACHABLE, when it is not

PLAY [WordPress Server - Install LEMP Stack with PHP 7.0 and MariaDB MySQL] ****

TASK [setup] *******************************************************************
System info:
Ansible 2.0.2.0; Darwin
Trellis at “Setup permalink structure for multisite installs too”

Failed to connect to the host via ssh.
fatal: [example.com]: UNREACHABLE! => {“changed”: false, “unreachable”: true}
to retry, use: --limit @server.retry

PLAY RECAP *********************************************************************
example.com : ok=3 changed=0 unreachable=1 failed=0
localhost : ok=0 changed=0 unreachable=0 failed=0

Did you configure your Trellis install to point to your project? https://github.com/roots/trellis/blob/master/group_vars/production/wordpress_sites.yml and https://github.com/roots/trellis/blob/master/hosts/production

Unless you changed your site name back to example.com for posting on Discourse

1 Like

If @kalenjohnson’s reply doesn’t resolve it, could you share the full verbose output (-vvvv) from running:

ansible-playbook server.yml -e env=production -vvvv
2 Likes

Thanks for the responses.

@kalenjohnson The example.com domain is for the purposes of posting here and I should have mentioned that.

I have run the playbook with the -vvvv option, and this is the output:

Using /Users/chinaski/Sites/small-projects/trellis/ansible.cfg as config file
Loaded callback output of type stdout, v2.0

PLAYBOOK: server.yml ***********************************************************
3 plays in server.yml

PLAY [Ensure necessary variables are defined] **********************************

TASK [Ensure environment is defined] *******************************************
task path: /Users/chinaski/Sites/small-projects/trellis/variable-check.yml:8
skipping: [localhost] => {“changed”: false, “skip_reason”: “Conditional check failed”, “skipped”: true}

PLAY [Determine Remote User] ***************************************************

TASK [remote-user : Require manual definition of remote-user] ******************
task path: /Users/chinaski/Sites/small-projects/trellis/roles/remote-user/tasks/main.yml:3
skipping: [example.com] => {“changed”: false, “skip_reason”: “Conditional check failed”, “skipped”: true}

TASK [remote-user : Check whether Ansible can connect as root] *****************
task path: /Users/chinaski/Sites/small-projects/trellis/roles/remote-user/tasks/main.yml:10
ESTABLISH LOCAL CONNECTION FOR USER: chinaski
localhost EXEC /bin/sh -c ‘( umask 22 && mkdir -p “echo $HOME/.ansible/tmp/ansible-tmp-1470840650.17-28503599837682” && echo “echo $HOME/.ansible/tmp/ansible-tmp-1470840650.17-28503599837682” )’
localhost PUT /var/folders/jd/dkv6c83s5j13l_pz9cbyq3340000gn/T/tmpuUBG8T TO /Users/chinaski/.ansible/tmp/ansible-tmp-1470840650.17-28503599837682/command
localhost EXEC /bin/sh -c ‘LANG=en_CA.UTF-8 LC_ALL=en_CA.UTF-8 LC_MESSAGES=en_CA.UTF-8 /usr/bin/python /Users/chinaski/.ansible/tmp/ansible-tmp-1470840650.17-28503599837682/command; rm -rf “/Users/chinaski/.ansible/tmp/ansible-tmp-1470840650.17-28503599837682/” > /dev/null 2>&1’
ok: [example.com → localhost] => {“changed”: false, “cmd”: [“ansible”, “example.com”, “-m”, “ping”, “-u”, “root”, “–connection=smart”, “–vault-password-file=.vault_pass”, “–timeout=10”, “–inventory-file=hosts”], “delta”: “0:00:01.442451”, “end”: “2016-08-10 07:50:51.683473”, “failed”: false, “failed_when_result”: false, “invocation”: {“module_args”: {“_raw_params”: “ansible example.com -m ping -u root --connection=‘smart’ --vault-password-file=‘.vault_pass’ --timeout=‘10’ --inventory-file=‘hosts’”, “_uses_shell”: false, “chdir”: null, “creates”: null, “executable”: null, “removes”: null, “warn”: true}, “module_name”: “command”}, “rc”: 2, “start”: “2016-08-10 07:50:50.241022”, “stderr”: “”, “stdout”: “\u001b[0;31mexample.com | FAILED! => {\n "changed": false, \n "failed": true, \n "module_stderr": "", \n "module_stdout": "/bin/sh: 1: /usr/bin/python: not found\r\n", \n "msg": "MODULE FAILURE", \n "parsed": false\n}\u001b[0m”, “stdout_lines”: [“\u001b[0;31mexample.com | FAILED! => {”, " "changed": false, ", " "failed": true, ", " "module_stderr": "", ", " "module_stdout": "/bin/sh: 1: /usr/bin/python: not found\r\n", ", " "msg": "MODULE FAILURE", “, " "parsed": false”, “}\u001b[0m”], “warnings”: }

TASK [remote-user : Set remote user for each host] *****************************
task path: /Users/chinaski/Sites/small-projects/trellis/roles/remote-user/tasks/main.yml:17
ok: [example.com] => {“ansible_facts”: {“ansible_user”: “admin”}, “changed”: false, “invocation”: {“module_args”: {“ansible_user”: “admin”}, “module_name”: “set_fact”}}

TASK [remote-user : Announce which user was selected] **************************
task path: /Users/chinaski/Sites/small-projects/trellis/roles/remote-user/tasks/main.yml:23
Note: Ansible will attempt connections as user = admin
ok: [example.com] => {}

PLAY [WordPress Server - Install LEMP Stack with PHP 7.0 and MariaDB MySQL] ****

TASK [setup] *******************************************************************
<example.com> ESTABLISH SSH CONNECTION FOR USER: admin
<example.com> SSH: EXEC ssh -C -vvv -o ForwardAgent=yes -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=admin -o ConnectTimeout=10 -o ControlPath=/Users/chinaski/.ansible/cp/ansible-ssh-%h-%p-%r example.com ‘/bin/sh -c ‘"’"’( umask 22 && mkdir -p “echo $HOME/.ansible/tmp/ansible-tmp-1470840651.91-108995243000570” && echo “echo $HOME/.ansible/tmp/ansible-tmp-1470840651.91-108995243000570” )‘"’"‘’
System info:
Ansible 2.0.2.0; Darwin
Trellis at “Setup permalink structure for multisite installs too”

Failed to connect to the host via ssh.
fatal: [example.com]: UNREACHABLE! => {“changed”: false, “unreachable”: true}
to retry, use: --limit @server.retry

PLAY RECAP *********************************************************************
example.com : ok=3 changed=0 unreachable=1 failed=0
localhost : ok=0 changed=0 unreachable=0 failed=0

1 Like

Thanks for the verbose output. It includes
/usr/bin/python: not found
which likely means your DO droplet is running Ubuntu 16.04 but you haven’t yet applied roots/trellis#626 (“Upgrade to Ubuntu 16.04 Xenial”).

Try updating your version of Trellis in order to take advantage of Ubuntu 16.04.
Or, just recreate your droplet with Ubuntu 14.04.

2 Likes

@fullyint Thanks for taking a look at this. I’ve changed the droplet to 14.04 and the playbook is running.

3 Likes

After provisioning I ran into the Letsencrypt issue documented on this thread: Let's Encrypt - agreement error

The upshot there was to pull down the latest version of trellis, so I did a (somewhat painful) merge with the current master branch of trellis. Running the new playbook sorted the Letsencrypt issue but presented me a warning about upgrading the os to 16.04. In the end I created a new ubuntu 16.04 droplet. I’m just starting with this particular site anyway.

1 Like

hello,

I’m facing the same problem, but the issue doesn’t involve not finding python. Instead, I’m getting an unreachable error despite being able to ssh successfully manually. The odd thing is that I was able to connect previously, but couldn’t make it through the playbook because I didn’t have my hostname set up correctly. Previously ansible was able to ssh to the IP before I had set up the hostname, but now neither the hostname nor the IP works. thanks for any help you might be able to provide. Here’s the verbose response:

PLAYBOOK: server.yml ***********************************************************
4 plays in server.yml

PLAY [Ensure necessary variables are defined] **********************************

TASK [Ensure environment is defined] *******************************************
task path: /Users/nic/Documents/curvy-yoga/studio/trellis/variable-check.yml:8
skipping: [localhost] => {“changed”: false, “skip_reason”: “Conditional check failed”, “skipped”: true}

PLAY [Determine Remote User] ***************************************************

TASK [remote-user : Require manual definition of remote-user] ******************
task path: /Users/nic/Documents/curvy-yoga/studio/trellis/roles/remote-user/tasks/main.yml:2
skipping: [staging.curvyyoga.studio] => {“changed”: false, “skip_reason”: “Conditional check failed”, “skipped”: true}

TASK [remote-user : Check whether Ansible can connect as root] *****************
task path: /Users/nic/Documents/curvy-yoga/studio/trellis/roles/remote-user/tasks/main.yml:9
ESTABLISH LOCAL CONNECTION FOR USER: nic
EXEC /bin/sh -c ‘( umask 77 && mkdir -p “echo $HOME/.ansible/tmp/ansible-tmp-1477966423.82-104690742009683” && echo ansible-tmp-1477966423.82-104690742009683=“echo $HOME/.ansible/tmp/ansible-tmp-1477966423.82-104690742009683” ) && sleep 0’
PUT /var/folders/n2/94s5_44x1w90_99l76s6vsgr0000gn/T/tmpE4gPy8 TO /Users/nic/.ansible/tmp/ansible-tmp-1477966423.82-104690742009683/command
EXEC /bin/sh -c ‘chmod u+x /Users/nic/.ansible/tmp/ansible-tmp-1477966423.82-104690742009683/ /Users/nic/.ansible/tmp/ansible-tmp-1477966423.82-104690742009683/command && sleep 0’
EXEC /bin/sh -c ‘LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8 /usr/local/opt/python/bin/python2.7 /Users/nic/.ansible/tmp/ansible-tmp-1477966423.82-104690742009683/command; rm -rf “/Users/nic/.ansible/tmp/ansible-tmp-1477966423.82-104690742009683/” > /dev/null 2>&1 && sleep 0’
ok: [staging.curvyyoga.studio → localhost] => {“changed”: false, “cmd”: [“ansible”, “staging.curvyyoga.studio”, “-m”, “raw”, “-a”, “whoami”, “-u”, “root”, “–connection=smart”, “–vault-password-file=.vault_pass”, “–timeout=10”, “–inventory-file=hosts”], “delta”: “0:00:01.350050”, “end”: “2016-10-31 21:13:45.322496”, “failed”: false, “failed_when_result”: false, “invocation”: {“module_args”: {“_raw_params”: “ansible staging.curvyyoga.studio -m raw -a whoami -u root --connection=‘smart’ --vault-password-file=‘.vault_pass’ --timeout=‘10’ --inventory-file=‘hosts’”, “_uses_shell”: false, “chdir”: null, “creates”: null, “executable”: null, “removes”: null, “warn”: true}, “module_name”: “command”}, “rc”: 3, “start”: “2016-10-31 21:13:43.972446”, “stderr”: “”, “stdout”: “\u001b[1;31mstaging.curvyyoga.studio | UNREACHABLE! => {\n "changed": false, \n "msg": "Failed to connect to the host via ssh.", \n "unreachable": true\n}\u001b[0m”, “stdout_lines”: [“\u001b[1;31mstaging.curvyyoga.studio | UNREACHABLE! => {”, " "changed": false, ", " "msg": "Failed to connect to the host via ssh.", “, " "unreachable": true”, “}\u001b[0m”], “warnings”: }

TASK [remote-user : Set remote user for each host] *****************************
task path: /Users/nic/Documents/curvy-yoga/studio/trellis/roles/remote-user/tasks/main.yml:16
ok: [staging.curvyyoga.studio] => {“ansible_facts”: {“ansible_user”: “ubuntu”}, “changed”: false, “invocation”: {“module_args”: {“ansible_user”: “ubuntu”}, “module_name”: “set_fact”}}

TASK [remote-user : Announce which user was selected] **************************
task path: /Users/nic/Documents/curvy-yoga/studio/trellis/roles/remote-user/tasks/main.yml:21
Note: Ansible will attempt connections as user = ubuntu
ok: [staging.curvyyoga.studio] => {}

TASK [remote-user : Load become password] **************************************
task path: /Users/nic/Documents/curvy-yoga/studio/trellis/roles/remote-user/tasks/main.yml:25
ok: [staging.curvyyoga.studio] => {“censored”: “the output has been hidden due to the fact that ‘no_log: true’ was specified for this result”}

PLAY [Install prerequisites] ***************************************************

TASK [Install Python 2.x] ******************************************************
task path: /Users/nic/Documents/curvy-yoga/studio/trellis/server.yml:17
<staging.curvyyoga.studio> ESTABLISH SSH CONNECTION FOR USER: ubuntu
<staging.curvyyoga.studio> SSH: EXEC ssh -C -q -o ForwardAgent=yes -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=ubuntu -o ConnectTimeout=10 -o ControlPath=/Users/nic/.ansible/cp/ansible-ssh-%h-%p-%r -tt staging.curvyyoga.studio ‘sudo -H -S -p “[sudo via ansible, key=eiwfeapvygzcsuxyrkaitbqwcqfzincd] password: " -u root /bin/sh -c '”’“‘echo BECOME-SUCCESS-eiwfeapvygzcsuxyrkaitbqwcqfzincd; sudo apt-get install -qq -y python-simplejson’”‘"’’
System info:
Ansible 2.1.2.0; Darwin
Trellis at “Enable per-site setup for permalink structure”

Failed to connect to the host via ssh.
fatal: [staging.curvyyoga.studio]: UNREACHABLE! => {“changed”: false, “unreachable”: true}
to retry, use: --limit @/Users/nic/Documents/curvy-yoga/studio/trellis/server.retry

If the playbook fails before completion on a new server while you’re iterating to get a working set of configs, and a difficult to debug issue arises, it’s often easiest to try again on a fresh server (recommended).

If you’d like to try to debug instead of rebuild, looks like you’re running OS X so just to be thorough, please ensure that your SSH key password is imported into Keychain by running ssh-add -K

If somehow this is an SSH key issue, you may want to try manually specifying the --key-file path to the applicable private SSH key, e.g., something like:

ansible-playbook server.yml -e env=staging --key-file=/Users/nic/.ssh/curvy_id_rsa

If that resolves it, that’s unusual, but you could define private_key_file in ansible.cfg to avoid having to use the --key-file option each time.

If the issue persists, it looks like Ansible can’t connect as root or as your admin_user ubuntu (the latter being the fallback if root can’t connect). When you successfully SSH manually, are you doing so as the user ubuntu? Can you successfully SSH as ubuntu? If you can only connect manually as some other_user, you would need to make admin_user: other_user

If none of the above helps, could you share which VPS provider you’re using (e.g., AWS, DigitalOcean, etc.)?

1 Like

Hi fullyint,

Thanks for the info! I was able to provision a new instance on DreamCompute (Dreamhost’s cloud hosting offering) and added my ssh keys to my Keychain, which seemed to do the trick. I am, however, facing the same issue where it fails at the ssmtp step because of “hostname: Name or service not known”. I’ll look for help on a thread covering that. Thanks!

After struggling with this same error Failed to connect to the host via ssh, I updated Ansible to the latest version to get better logs:

pip install --upgrade ansible

Then, when I repeated the command:

ansible-playbook server.yml -e env=production -vvvv

I was able to figure out that this was the real output:

195.252.101.79 | UNREACHABLE! => {
“changed”: false,
“msg”: “Failed to connect to the host via ssh: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r\n@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @\r\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r\nIT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!\r\nSomeone could be eavesdropping on you right now (man-in-the-middle attack)!\r\nIt is also possible that a host key has just been changed.\r\nThe fingerprint for the RSA key sent by the remote host is\nSHA256:SkHmBnyVfDXKSR87YkseQh/yss9RKFUhk7r+/uN45tQ.\r\nPlease contact your system administrator.\r\nAdd correct host key in /home/vagrant/.ssh/known_hosts to get rid of this message.\r\nOffending RSA key in /home/vagrant/.ssh/known_hosts:1\r\n remove with:\r\n ssh-keygen -f "/home/vagrant/.ssh/known_hosts" -R 195.252.101.79\r\nRSA host key for 195.252.101.79 has changed and you have requested strict checking.\r\nHost key verification failed.\r\n”,
“unreachable”: true
}
195.168.50.5 | SUCCESS => {
“changed”: false,
“invocation”: {
“module_args”: {
“data”: null
},
“module_name”: “ping”
},
“ping”: “pong”
}

Because the RSA key from host was changed I needed to update the known_hosts into the vagrant VM.

I’ve ssh into it and executed the command ssh-keygen -R 195.252.101.79 to regenerate the fingerprints from the host.

And I was finally able to execute the server.yml without errors.

Hope it helps someone!

1 Like