Aller au contenu principal

GitLab CI

Bêta

Fonctionnalité en cours de déploiement. L'interface décrite ici est celle de la prochaine livraison : elle peut encore évoluer, et n'est pas forcément activée sur votre tenant.

Ce pipeline valide les manifestes sur chaque branche et les applique sur main, sans aucun secret stocké dans GitLab. Il suppose un trust OIDC déclaré pour le projet.

Prérequis​

sng tenant oidc create gitlab-deploy \
--gitlab-project acme/infra --ref main \
--claim project_id=4242 --claim ref_protected=true
sng tenant policy attach readwrite --oidc-trust gitlab-deploy

Pour que sng validate et sng plan tournent aussi sur les merge requests, déclarez un second trust en lecture seule, toutes branches :

sng tenant oidc create gitlab-review --gitlab-project acme/infra --ref '*' --claim project_id=4242
sng tenant policy attach readonly --oidc-trust gitlab-review

Installer la CLI dans le job​

Tant que les binaires ne sont pas publiés, la CLI se construit depuis les sources du dépôt sng-cli. Dans un pipeline, faites-le une fois dans un job dédié et passez le binaire en artefact :

.gitlab-ci.yml
stages: [tools, verify, deploy]

build-sng:
stage: tools
image: golang:1.27
script:
- git clone --depth 1 "https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/stackngo/sng-cli.git" /tmp/sng-cli
- make -C /tmp/sng-cli build
- mkdir -p bin && cp /tmp/sng-cli/bin/sng bin/sng
artifacts:
paths: [bin/sng]
expire_in: 1 day
cache:
key: sng-cli
paths: [/go/pkg/mod]

Le dépôt sng-cli doit être accessible au CI_JOB_TOKEN du projet (même groupe, ou accès accordé dans ses réglages). Si votre équipe publie déjà un binaire ou une image contenant sng, remplacez ce job par un simple téléchargement.

Valider sur chaque branche​

.sng:
image: debian:bookworm-slim
needs: [build-sng]
variables:
STNG_TENANT: acme
GIT_DEPTH: "1"
id_tokens:
STNG_OIDC_TOKEN:
aud: https://api.dev.stackngo.fr
before_script:
- export PATH="$CI_PROJECT_DIR/bin:$PATH"
- sng config create >/dev/null

validate:
extends: .sng
stage: verify
script:
- sng validate infra/
- sng plan infra/
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH

id_tokens demande à GitLab un jeton OIDC d'audience égale à l'URL de l'API et le place dans STNG_OIDC_TOKEN. La CLI le détecte et ouvre la session sur STNG_TENANT.

Sur une merge request, le trust gitlab-review (toutes branches, readonly) ouvre la session ; sur main, gitlab-deploy. Si les deux correspondent, fixez STNG_OIDC_TRUST dans chaque job.

Déployer sur main​

deploy:
extends: .sng
stage: deploy
variables:
STNG_TENANT: acme
STNG_OIDC_TRUST: gitlab-deploy
script:
- sng apply infra/
- sng app describe api
environment:
name: production
url: https://api-api.acme.dev.stackngo.app
rules:
- if: $CI_COMMIT_BRANCH == "main"
apply acme — 3 object(s)
…

Attendre la convergence​

sng apply revient dès que l'état désiré est écrit. Pour que le job échoue si l'application ne démarre pas, bouclez sur le status :

- |
for i in $(seq 1 30); do
ready=$(sng app describe api --json | python3 -c 'import sys,json; print(json.load(sys.stdin).get("ready", False))')
[ "$ready" = "True" ] && exit 0
sleep 10
done
sng app describe api; exit 1

Gardez l'intervalle à 10 s : la limite de débit est partagée par tous les jobs du runner.

Variables utiles​

VariableRôle
STNG_TENANTTenant visé (obligatoire)
STNG_OIDC_TOKENRempli par id_tokens
STNG_OIDC_TRUSTDésambiguïse si plusieurs trusts correspondent
STNG_CLUSTERAlternative à sng config use-cluster

Aucune variable CI « masquée » n'est nécessaire : il n'y a pas de secret.

Dépannage​

  • no CI OIDC token : le job n'a pas de bloc id_tokens, ou il est dans un extends non repris.
  • 401 invalid identity token : le sub du jeton ne correspond à aucun trust. Sur une branche non protégée, ref_protected=true exclut le jeton : c'est voulu.
  • 403 forbidden sur apply : le trust utilisé n'a que readonly. Vérifiez STNG_OIDC_TRUST.
  • Le job build-sng échoue sur le git clone : le CI_JOB_TOKEN n'a pas accès au dépôt sng-cli.

Voir aussi​