2021-12-19 / Bartłomiej Kurek
Jenkins: SSH Pipeline Steps

Do deploymentu zdalnego w Jenkins możemy użyć pluginu SSH Pipeline Steps. Plugin ten pozwala nam określić docelowy system w skrypcie pipeline. Dane autentykacyjne wykorzystywane w pipeline możemy uzyskać z konfiguracji samego systemu Jenkins.

Pipeline

pipeline {
    agent any 

    stages {
        stage("Deploy") { 
            steps {
                script {
                    def remote = [:]
                    remote.name = "whatever"
                    remote.host = "172.17.0.1"
                    remote.port = 22
                    remote.allowAnyHosts = true

                    withCredentials(
                        [
                            usernamePassword(
                                credentialsId:    "deploy",
                                usernameVariable: "USERNAME",
                                passwordVariable: "PASSWORD"
                            )
                        ]
                    ) {
                        remote.user = USERNAME
                        remote.password = PASSWORD
                        sshPut remote: remote, from: "/tmp/script.sh", into: "./script.sh"
                        sshCommand remote: remote, command: "sh script.sh"
                    }
                }
            }
        }
    }
}

Powyższy pipeline na etapie "Deploy" wykonuje skrypt. W celu użycia SSH Pipeline Steps wymagany jest block script(!). Umieszczamy w nim definicję systemu zdalnego (host, port) oraz komendy. Plugin dostarcza nam m.in. komendy: sshPut, sshGet, sshCommand. Jeśli korzystamy z Jenkins Credentials, to możemy się do nich odnieść poprzez withCredentials. Moglibyśmy również wykorzystać tutaj klucz ssh, zainteresowanych szczegółami odsyłam do: repozytorium i pełnej dokumentacja pluginu.
W powyższym przykładzie korzystam z przechowywanej w Jenkins konfiguracji danych autentykacyjnych (credentials) dostępnych pod id deploy. Jako artefaktu używam tutaj skryptu shellowego, który kopiowany jest na system docelowy, a następnie tam wykonywany. Skrypt wypisuje po prostu ciąg "Hello World" bezpośrednio na standardowe wyjście.

#!/bin/sh

echo "Hello World"

Demo

Scenariusz: pipeline w Jenkins wykonuje etap deploy. Jenkins uruchomiony jest na innej maszynie (tutaj docker). Hostem docelowym jest mój komputer, na którym uruchomiony jest demon SSH oraz istnieje użytkownik deploy. Logowanie odbywa się przy użyciu hasła. Pipeline kopiuje na mój komputer skrypt sh (sshPut), a następnie go wykonuje (sshCommand).

Poniższe video demonstruje realizację tego pipeline na czystym jenkinsie uruchomionym w dockerze.

Video: MP4, 6.4M, 1920x1080. Duration: 00:05:48 Link

Omówienie etapów w filmie

Instalacja

  • uruchamiam oficjalny obraz jenkins/jenkins:lts w kontenerze docker, dodaję publikację portu 8080
$ docker run -it -d --name jenkins -p 8080:8080 jenkins/jenkins:lts
  • wyświetlam logi kontenera, gdyż w nich jest wygenerowane automatycznie przez instalację Jenkin hasło administratora
$ docker logs -f jenkins
  • otwieram stronę Jenkins w przeglądarce (http://localhost:8080)
  • podaję hasło i przechodzę domyślną instalację

Stworzenie użytkownika deploy

  • w swoim systemie tworzę użytkownika deploy, nadaję mu hasło
# adduser deploy
  • uruchamiam shell w kontenerze i upewniam się, że kontener ma dostęp po ssh do mojego systemu głównego (adres ip 172.17.0.1 (docker bridge))
$ docker exec -it -u 0 jenkins /bin/bash
(docker) $ ssh deploy@172.17.0.1

Pipeline

  • dodaję pipeline, nazywam go ssh-pipeline
  • ustawiam pipeline script

Artefakt

  • w dockerze uruchamiam ponownie shell
  • tworzę skrypt shellowy: /tmp/script.sh

Instalacja pluginów

  • instaluję plugin: SSH Pipeline Steps
  • instaluję plugin: SSH

Credentials

  • w konfiguracji Jenkins, w sekcji "Manage Credentials" dodaję dane autentykacyjne: username, password, ID (deploy - nazwa, do której odwołuje się withCredentials w skrypcie pipeline)

Uruchomienie pipeline

  • uruchamiam pipeline
  • sprawdzam logi wykonania pipeline