Cloner des projets privés dans un runner Gitlab CI

Gitlab n'est aujourd'hui plus un simple outil permettant d'héberger son code sur Git au travers d'une interface agréable. Non, Gitlab est aujourd'hui un environnement extrêmement complet et orienté vers une culture DevOps tout en un. La plateforme permet aujourd'hui de stocker son code, gérer des projets, faire de l'intégration et du déploiement continu (incluant un outil de monitoring) au sein d'un outil unique.

C'est pour toutes ces raisons que nous utilisons Gitlab au quotidien chez Opéra Energie. Pour éviter d'avoir à gérer notre infrastructure, nous utilisons Gitlab et les outils associés en mode SaaS. Nous travaillons sur une plateforme ayant une architecture orientée services et où chacun de ces derniers est isolés au sein de son propre dépôt de code et est testé via un pipeline Gitlab CI.

Il arrive que certains projets requièrent des dépendances externes pouvant être gérés dans des dépôts privés. Dans ce cas-là, il est nécessaire que le runner Gitlab CI ait accès à ce dernier pour pouvoir cloner le projet en question. Comme je l'ai signalé précédemment, nous utilisons Gitlab (et Gitlab CI) en mode SaaS et il nous ait donc impossible d'accéder aux serveurs des runners pour y déposer la clé SSH permettant de récupérer les projets privés (sans compter que nous exécutons toutes les actions des runners au sein de conteneurs Docker).

Afin de contourner ce problème, nous injectons dynamiquement la configuration nécessaire durant l'exécution de notre pipeline Gitlab CI. Pour cela, nous avons commencé à créer une clé SSH uniquement dédiée à une utilisation des dépôts au sein des runners de Gitlab. La clé privée est alors utilisée en tant que Deploy Key des projets privés dont nous avons besoin.

Une fois configuré, nous allons ajouter la clé privée comme une variable d'environnement des runners et qui sera dynamiquement injectée dans le runner par Gitlab au moment de l'exécution de notre pipeline. Il ne reste ensuite plus qu'à utiliser notre clé SSH lors de l'exécution de nos différentes tâches :

image: alpine:3.6

before_script:
    - apk add --update git openssh-client
    - mkdir -p ~/.ssh
    - echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
    - eval $(ssh-agent -s)
    - echo "$SECRET_KEY" | ssh-add -

test:unit:
    script:
        - ./run-unit-test.sh

test:functional:
    script:
        - ./run-functional-test.sh