I’m using Ansible 1.5.3 and Git with ssh agent forwarding (https://help.github.com/articles/using-ssh-agent-forwarding). I can log into the server that I am managing with Ansible and test that my connection to git is correctly configured:
ubuntu@test:~$ ssh -T [email protected]
Hi gituser! You've successfully authenticated, but GitHub does not provide shell access.
I can also clone and update one of my repos using this account so my git configuration looks good and uses ssh forwarding when I log into my server directly via ssh.
The problem: When I attempt the same test shown above using the Ansible command module. It fails with “Permission denied”. Part of the Ansible output (with verbose logging) looks like this:
failed: [xxx.xxxxx.com] => {"changed": true, "cmd": ["ssh", "-T", "[email protected]"], "delta": "0:00:00.585481", "end": "2014-06-09 14:11:37.410907", "rc": 255, "start": "2014-06-09 14:11:36.825426"}
stderr: Permission denied (publickey).
Here is the simple playbook that runs this command:
- hosts: webservers
sudo: yes
remote_user: ubuntu
tasks:
- name: Test that git ssh connection is working.
command: ssh -T [email protected]
The question: why does everything work correctly when I manually log in via ssh and run the command but fail when the same command is run as the same user via Ansible?
I will post the answer shortly if no one else beats me to it. Although I am using git to demonstrate the problem, it could occur with any module that depends on ssh agent forwarding. It is not specific to Ansible but I suspect many will first encounter the problem in this scenario.
The problem is resolved by removing this line from the playbook:
sudo: yes
When sudo is run on the remote host, the environment variables set by ssh during login are no longer available. In particular, SSH_AUTH_SOCK, which "identifies the path of a UNIX-domain socket used to communicate with the agent" is no longer visible so ssh agent forwarding does not work.
Avoiding sudo when you don't need it is one way to work around the problem. Another way is to ensure that SSH_AUTH_SOCK sticks around during your sudo session by creating a sudoers file:
/etc/sudoers:
Defaults env_keep += "SSH_AUTH_SOCK"