Shaung Shaung - 11 months ago 104
Git Question

Public key denied when fetching from bitbucket in Ansbile with Jenkins

What I am trying to do:

I have a 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)--->

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

What's going wrong:

The ansible script fails connecting to bitbucket with
Public key denied

What I have checked:

  1. The public key on jenkins has been added to deploy keys list and it do works without permission problems.

  2. ssh-agent is running on the jenkins node and the private key on jenkins has been added.

  3. AllowFowardAgent has been set to yes on the server.

  4. The ansible plugin for jenkins copies the private key to /tmp and use it when running playbooks. It's not the same file path to what I have
    -ed, but I don't think that's causing the problem.

The jenkins code

Before running 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

cat ~/.ssh/config

git clone

The ansible code

My playbook:

- name: check SSH_AUTH_SOCK
shell: echo "$SSH_AUTH_SOCK"

- name: check ssh-agent forwarding
shell: ssh -T

My ansible.cfg:

ssh_args = -o ForwardAgent=yes -o StrictHostKeyChecking=no -C -o ControlMaster=auto -o ControlPersist=60s

The output

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": []}

ssh -T

11:29:09 fatal: [testserver]: FAILED! => {"changed": true, "cmd": "ssh -T", "delta": "0:00:05.009720", "end": "2016-09-06 11:29:09.879430", "failed": true, "invocation": {"module_args": {"_raw_params": "ssh -T", "_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": []}

Answer Source

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.