I have an Ansible script which does a git clone from Bitbucket, and I'm running that script from jenkins via the Ansible plugin.
The route:
Jenkins server ---(ansible)---> App server ----(git)---> bitbucket.org
I'm trying to connect to the repo on Bitbucket from the App server, using the ssh private key on the Jenkins server, which should be achievable with the help of ssh-agent
.
The Ansible script fails connecting to Bitbucket with Public key denied
.
ssh-agent
is running on the jenkins node and the private key on jenkins has been added.AllowFowardAgent
has been set to yes
on the server./tmp
and use it when running playbooks. It's not the same file path to what I have ssh-add
-ed, but I don't think that's causing the problem. Before running the Ansible task I have the below shell script run first:
eval `ssh-agent -s`
ssh-add ~/.ssh/id_rsa
cat >~/.ssh/config <<EOL
Host *
ForwardAgent yes
EOL
cat ~/.ssh/config
git clone git@bitbucket.org:myuser/myrepo.git
My playbook:
- name: check SSH_AUTH_SOCK
shell: echo "$SSH_AUTH_SOCK"
- name: check ssh-agent forwarding
shell: ssh -T git@bitbucket.org
My ansible.cfg
:
[ssh_connection]
ssh_args = -o ForwardAgent=yes -o StrictHostKeyChecking=no -C -o ControlMaster=auto -o ControlPersist=60s
In my Ansible script I can see that SSH_AUTH_SOCK
is set:
11:29:04 changed: [testserver] => {"changed": true, "cmd": "echo \"$SSH_AUTH_SOCK\"", "delta": "0:00:00.007881", "end": "2016-09-06 11:29:04.576963", "invocation": {"module_args": {"_raw_params": "echo \"$SSH_AUTH_SOCK\"", "_uses_shell": true, "chdir": null, "creates": null, "executable": null, "removes": null, "warn": true}, "module_name": "command"}, "rc": 0, "start": "2016-09-06 11:29:04.569082", "stderr": "", "stdout": "/tmp/ssh-WnmHgtzMBS/agent.13630", "stdout_lines": ["/tmp/ssh-WnmHgtzMBS/agent.13630"], "warnings": []}
But ssh -T git@bitbucket.org
fails:
11:29:09 fatal: [testserver]: FAILED! => {"changed": true, "cmd": "ssh -T git@bitbucket.org", "delta": "0:00:05.009720", "end": "2016-09-06 11:29:09.879430", "failed": true, "invocation": {"module_args": {"_raw_params": "ssh -T git@bitbucket.org", "_uses_shell": true, "chdir": null, "creates": null, "executable": null, "removes": null, "warn": true}, "module_name": "command"}, "rc": 255, "start": "2016-09-06 11:29:04.869710", "stderr": "Error reading response length from authentication socket.\r\nPermission denied (publickey).", "stdout": "", "stdout_lines": [], "warnings": []}
When you execute ssh-agent -s
it outputs a series of environment variables which are required for agent forwarding feature of SSH, for example:
SSH_AUTH_SOCK=/var/folders/nw/2vnhg_gj77v_cyfv0p1vdfj80000gn/T//ssh-alCh0yLKdoci/agent.53532; export SSH_AUTH_SOCK; SSH_AGENT_PID=53533; export SSH_AGENT_PID; echo Agent pid 53533;
When you run it through eval
these commands get executed in the current shell session and you can see the output of the last one (echo
):
Agent pid 53533
The environment variables however are set for the current process and subprocesses. If you call Ansible playbook from a different process, they won't be seen.
As you already figured out, the SSH Agent Plugin for Jenkins takes care so that other processes (like Ansible plugin) will inherit these environment variables.