How do I use SSH in a Jenkins pipeline?

Viewed 93063

I have some Jenkins jobs defined using a Jenkins Pipeline Model Definition, which builds NPM projects. I use Docker containers to build these projects (using a common image with just Node.js + npm + yarn).

The results of the builds are contained in the dist/ folder that I zipped using a zip pipeline command.

I want to copy this ZIP file to another server using SSH/SCP (with private key authentication). My private key is added to the Jenkins environment (credentials manager), but when I use Docker containers, an SSH connection cannot be established.

I tried to add agent { label 'master' } to use the master Jenkins node for file transfer, but it seems to create a clean workspace with new Git fetch, and without my built files.

After I tried the SSH Agent Plugin, I have this output:

Identity added: /srv/jenkins3/workspace/myjob-TFD@tmp/private_key_370451445598243031.key (rsa w/o comment)
[ssh-agent] Started.
[myjob-TFD] Running shell script
+ scp -r dist test@myremotehost:/var/www/xxx
$ docker exec bfda17664965b14281eef8670b34f83e0ff60218b04cfa56ba3c0ab23d94d035 env SSH_AGENT_PID=1424 SSH_AUTH_SOCK=/tmp/ssh-k658r0O76Yqb/agent.1419 ssh-agent -k
unset SSH_AUTH_SOCK;
unset SSH_AGENT_PID;
echo Agent pid 1424 killed;
[ssh-agent] Stopped.
Host key verification failed.
lost connection

How do I add a remote host as authorized?

4 Answers

I had a similar issue. I did not use the label 'master', and I identified that the file transfer works across slaves when I do it like this:

Step 1 - create SSH keys in a remote host server, include the key to authorized_keys

Step 2 - Create credential using SSH keys in Jenkins, use the private key from the remote host

Use the SSH agent plugin:

stage ('Deploy') {
    steps{
        sshagent(credentials : ['use-the-id-from-credential-generated-by-jenkins']) {
            sh 'ssh -o StrictHostKeyChecking=no user@hostname.com uptime'
            sh 'ssh -v user@hostname.com'
            sh 'scp ./source/filename user@hostname.com:/remotehost/target'
        }
    }
}

Like @haschibaschi recommends, I also use the ssh-agent plugin. I have a need to use my personal UID credentials on the remote machine, because it doesn't have any UID Jenkins account. The code looks like this (using, for example, my personal UID="myuid" and remote server hostname="non_jenkins_svr":

sshagent(['e4fbd939-914a-41ed-92d9-8eededfb9243']) {
    // 'myuid@' required for scp (this is from UID jenkins to UID myuid)
    sh "scp $WORKSPACE/example.txt myuid@non_jenkins_svr:${dest_dir}"
}

The ID e4fbd939-914a-41ed-92d9-8eededfb9243 was generated by the Jenkins credentials manager after I created a global domain credentials entry.

After creating the credentials entry, the ID is found under the "ID" column on the credentials page. When creating the entry, I selected type 'SSH Username with private key' ('Kind' field), and copied the RSA private key I had created for this purpose under the myuid account on host non_jenkins_svr without a passphrase.

Related