fuer mehrere Projekte sauber verwalten
Wer in GitLab mehr als eine Handvoll Projekte betreut, merkt schnell: Variablen und Runner pro Projekt einzeln zu pflegen, wird zum Vollzeitjob. Gruppenweite Konfiguration loest genau dieses Problem.
Inhaltsverzeichnis
- 1. Warum Projekt-Variablen bei mehreren Projekten an ihre Grenzen stossen
- 2. Group-Variablen anlegen und Sichtbarkeit steuern
- 3. Vererbungsreihenfolge: Wenn Projekt- und Group-Variable kollidieren
- 4. Shared Runner: Von der GitLab-Instanz bereitgestellt
- 5. Group Runner: Der Mittelweg fuer Organisationen
- 6. Project Runner: Isolation fuer besonders sensible Pipelines
- 7. Runner gezielt ueber Tags und rules ansteuern
- 8. Variablen-Hygiene bei wachsender Projektzahl
- 9. Praxisbeispiel: Drei Runner-Ebenen in einer Organisation kombiniert
- 10. Zusammenfassung
- 11. FAQ
1. Warum Projekt-Variablen bei mehreren Projekten an ihre Grenzen stossen
In vielen Organisationen entsteht die CI/CD-Konfiguration organisch: Ein Projekt bekommt eine Deploy-Variable, das naechste kopiert sie, das dritte weicht schon leicht ab, weil jemand einen Tippfehler gemacht hat. Nach einem Jahr existieren funf verschiedene Varianten derselben API-Key-Variable in funf verschiedenen Projekten, und niemand weiss mehr zuverlaessig, welche davon noch gueltig ist. Das ist kein hypothetisches Problem, sondern der Normalfall in gewachsenen GitLab-Instanzen mit zehn oder mehr aktiven Repositories.
Group-Level Variablen loesen dieses Problem an der Wurzel, indem sie die Variable genau einmal definieren und an alle Projekte innerhalb der Gruppe und ihrer Untergruppen vererben. Eine Aenderung an einer Stelle wirkt sich sofort auf alle Pipelines aus, die darauf zugreifen, ganz ohne manuelles Nachpflegen in jedem einzelnen Projekt. Der Effekt ist besonders gross bei Werten, die sich regelmaessig aendern, etwa rotierende Deploy-Tokens oder Registry-Zugangsdaten, bei denen ein vergessenes Projekt sonst mit veralteten Credentials fehlschlaegt.
2. Group-Variablen anlegen und Sichtbarkeit steuern
Group-Variablen werden unter Settings, CI/CD, Variables auf Gruppenebene angelegt, nicht im einzelnen Projekt. Jede Variable erhaelt dort dieselben Optionen wie eine Projekt-Variable: Protected schraenkt die Sichtbarkeit auf geschuetzte Branches und Tags ein, Masked verhindert das Auftauchen im Job-Log, und Environment Scope erlaubt es, denselben Variablennamen fuer verschiedene Umgebungen mit unterschiedlichen Werten zu belegen. Gerade Masked und Protected sollten fuer alles, was nach einem Secret aussieht, ohne Ausnahme aktiviert werden.
Ein haeufiger Fehler ist, saemtliche Variablen einer Organisation auf die oberste Gruppenebene zu legen, obwohl nur eine Teilmenge der Projekte sie tatsaechlich braucht. Besser ist eine Staffelung ueber Untergruppen: Eine allgemeine Registry-URL gehoert auf die oberste Ebene, ein Deploy-Key fuer eine bestimmte Produktlinie dagegen nur auf die Untergruppe, die diese Produkte enthaelt. So bleibt die Zugriffsflaeche pro Team klein, und ein kompromittiertes Projekt-Token in einem Team zieht nicht automatisch alle anderen Teams in Mitleidenschaft.
# .gitlab-ci.yml eines Projekts innerhalb der Gruppe
# Die Variablen DEPLOY_TOKEN und REGISTRY_URL kommen NICHT aus dieser Datei,
# sondern werden auf Gruppenebene unter Settings > CI/CD > Variables gepflegt.
stages:
- build
- deploy
deploy_staging:
stage: deploy
image: alpine:3.20
script:
- echo "Deploying to $REGISTRY_URL"
- curl -H "Authorization: Bearer $DEPLOY_TOKEN" "$REGISTRY_URL/api/deploy"
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
3. Vererbungsreihenfolge: Wenn Projekt- und Group-Variable kollidieren
GitLab loest Namenskonflikte nach einer klaren Prioritaet auf: Eine Variable, die direkt im Projekt definiert ist, ueberschreibt eine gleichnamige Variable aus der Gruppe, und eine Untergruppen-Variable ueberschreibt wiederum eine Variable aus einer uebergeordneten Gruppe. Das erlaubt gezielte Ausnahmen, etwa wenn ein einzelnes Projekt fuer einen Testzeitraum eine andere Registry ansprechen soll, ohne dass dafuer die gesamte Gruppenkonfiguration angefasst werden muss.
Diese Flexibilitaet hat allerdings eine Kehrseite: Wenn ein Projekt scheinbar grundlos die falsche Konfiguration nutzt, liegt die Ursache oft in einer laengst vergessenen Projekt-Variable, die eine neuere Group-Variable stillschweigend ueberschreibt. Es lohnt sich, bei der Fehlersuche zunaechst systematisch alle drei Ebenen zu pruefen, von der obersten Gruppe ueber Untergruppen bis zum Projekt selbst, statt vorschnell von einem Runner- oder Netzwerkproblem auszugehen. Ein regelmaessiger Audit, welche Projekt-Variablen eine Group-Variable ueberschreiben, deckt solche Karteileichen zuverlaessig auf.
4. Shared Runner: Von der GitLab-Instanz bereitgestellt
Shared Runner werden zentral von der GitLab-Instanz beziehungsweise bei GitLab.com von GitLab selbst betrieben und stehen allen Projekten der Instanz zur Verfuegung, sofern sie nicht explizit deaktiviert wurden. Ihr grosser Vorteil ist der Nullaufwand bei der Verwaltung: Es muss keine eigene Infrastruktur betrieben, gepatcht oder skaliert werden. Fuer kleinere Teams oder Projekte mit moderatem Pipeline-Aufkommen ist das oft die richtige Wahl, insbesondere wenn keine speziellen Hardware-Anforderungen wie GPUs oder sehr grosse Caches bestehen.
Der Nachteil zeigt sich bei hoher Auslastung oder speziellen Anforderungen: Shared Runner werden von vielen Projekten gleichzeitig genutzt, was zu Wartezeiten in der Job-Queue fuehren kann, wenn zur selben Zeit viele andere Teams ebenfalls Pipelines auf denselben Pool ausloesen. Bei selbstgehosteten GitLab-Instanzen bedeutet ein Shared Runner ausserdem, dass jedes Projekt der Instanz theoretisch Jobs darauf ausfuehren kann, was aus Sicherheitssicht bei sensiblen Deploy-Pipelines oft unerwuenscht ist.
5. Group Runner: Der Mittelweg fuer Organisationen
Ein Group Runner wird auf Gruppenebene registriert und steht ausschliesslich Projekten innerhalb dieser Gruppe und ihrer Untergruppen zur Verfuegung. Das macht ihn zur naheliegenden Wahl fuer Organisationen, die mehrere verwandte Projekte betreuen, etwa alle Repositories eines Produktteams, und dabei sowohl Ressourcen teilen als auch die Zugriffsflaeche gegenueber fremden Projekten der Instanz begrenzen wollen. Ein Group Runner mit spezieller Hardware, etwa mehr RAM fuer Build-intensive Jobs, muss so nur einmal eingerichtet werden statt in jedem Projekt einzeln.
Die Registrierung erfolgt unter Settings, CI/CD, Runners auf Gruppenebene, wo ein Registrierungstoken erzeugt wird, das anschliessend beim Runner-Setup auf der Zielmaschine verwendet wird. Wichtig ist, den Runner mit sprechenden Tags zu versehen, etwa docker oder high-memory, damit Jobs in der .gitlab-ci.yml gezielt darauf routen koennen und nicht versehentlich auf einem falsch dimensionierten Runner landen. Ohne Tags greift GitLab auf eine Standardzuordnung zurueck, die in gemischten Umgebungen schnell zu ueberraschenden Ergebnissen fuehrt.
build_backend:
stage: build
tags:
- docker
- high-memory
image: node:20-alpine
script:
- npm ci
- npm run build
6. Project Runner: Isolation fuer besonders sensible Pipelines
Ein Project Runner ist ausschliesslich einem einzigen Projekt zugeordnet und wird typischerweise dort eingesetzt, wo Isolation wichtiger ist als geteilte Ressourcen: produktionsnahe Deploy-Pipelines, Projekte mit besonders strengen Compliance-Anforderungen oder Jobs, die auf sensible interne Netzwerke zugreifen muessen, die nicht jedes andere Projekt der Organisation erreichen soll. Da nur dieses eine Projekt Jobs auf dem Runner ausfuehren kann, ist die Angriffsflaeche minimal, was den zusaetzlichen Verwaltungsaufwand oft rechtfertigt.
In der Praxis empfiehlt sich eine Mischstrategie: Der Grossteil der Build- und Test-Jobs laeuft auf Group Runnern, waehrend nur die tatsaechliche Deploy-Stufe auf einen dedizierten Project Runner mit Zugriff auf die Produktionsumgebung ausgelagert wird. Diese Aufteilung reduziert die Zahl der Maschinen mit Produktionszugang drastisch, ohne die Geschwindigkeit der uebrigen Pipeline-Schritte zu beeintraechtigen, da diese weiterhin von der Parallelitaet der geteilten Runner profitieren.
7. Runner gezielt ueber Tags und rules ansteuern
Sobald mehrere Runner-Ebenen parallel existieren, muss jede Pipeline explizit steuern, welcher Job auf welchem Runner landet. Das geschieht ueber die tags-Direktive im Job: GitLab waehlt unter allen verfuegbaren Runnern, die alle angegebenen Tags besitzen, automatisch einen passenden aus. Ein Job ohne Tags kann grundsaetzlich auf jedem Runner laufen, der keine Tag-Pflicht erzwingt, was in gemischten Umgebungen aus Shared, Group und Project Runnern zu unvorhersehbarem Verhalten fuehren kann, wenn nicht klar dokumentiert ist, welcher Runner welche Tags traegt.
Fuer produktionskritische Jobs empfiehlt sich zusaetzlich eine Kombination aus tags und rules, um sicherzustellen, dass ein Deploy-Job wirklich nur auf dem dafuer vorgesehenen Project Runner und nur auf dem geschuetzten main-Branch ausgefuehrt wird. Diese doppelte Absicherung verhindert, dass ein versehentlich falsch konfigurierter Feature-Branch-Job auf einem Runner mit Produktionszugriff landet, selbst wenn jemand aus Versehen den Tag kopiert, aber die rules-Bedingung vergisst.
deploy_production:
stage: deploy
tags:
- project-runner-prod
rules:
- if: '$CI_COMMIT_BRANCH == "main" && $CI_PIPELINE_SOURCE == "push"'
when: manual
environment:
name: production
url: https://example.com
8. Variablen-Hygiene bei wachsender Projektzahl
Mit steigender Projektzahl wird es zunehmend wichtig, Variablen konsequent zu benennen und zu dokumentieren. Ein bewaehrtes Muster ist ein Praefix pro Zweck, etwa DEPLOY_ fuer alles rund um Deployments und REGISTRY_ fuer Container-Registry-Zugaenge, kombiniert mit einer kurzen Beschreibung im Description-Feld, das GitLab fuer jede Variable anbietet. Ohne diese Disziplin sammeln sich ueber Monate Variablen an, deren urspruenglicher Zweck niemand mehr rekonstruieren kann, und aus Vorsicht loescht sie dann auch niemand mehr.
Ein regelmaessiger Review-Zyklus, etwa vierteljaehrlich, bei dem alle Group- und Project-Variablen durchgegangen werden, verhindert diese Ansammlung von totem Ballast. Dabei lohnt sich besonders die Frage, ob eine Variable noch von einer aktiven Pipeline referenziert wird, was sich einfach per Projektsuche nach dem Variablennamen in allen .gitlab-ci.yml-Dateien der Gruppe pruefen laesst. Variablen, die seit Monaten in keiner Datei mehr auftauchen, koennen in der Regel gefahrlos entfernt werden.
9. Praxisbeispiel: Drei Runner-Ebenen in einer Organisation kombiniert
Ein konkretes Setup fuer eine Organisation mit zehn Projekten koennte so aussehen: Auf oberster Gruppenebene liegen allgemeine Variablen wie REGISTRY_URL und ein Shared Runner fuer schnelle, unkritische Lint- und Test-Jobs. Auf Untergruppenebene, etwa fuer ein bestimmtes Produktteam, kommen ein Group Runner mit mehr Ressourcen fuer Build-Jobs sowie eine Group-Variable fuer den teamspezifischen Staging-Zugang hinzu. Nur die eigentlichen Produktions-Deploy-Jobs der wichtigsten Projekte laufen schliesslich auf einem dedizierten Project Runner mit eigener Project-Variable fuer das Produktions-Token.
Diese dreistufige Kombination sorgt dafuer, dass die grosse Masse der Pipeline-Arbeit von geteilten, effizient ausgelasteten Runnern erledigt wird, waehrend nur der schmale, sicherheitskritische Pfad isolierte Ressourcen bekommt. Die folgende Tabelle fasst zusammen, wann welche Runner-Ebene die richtige Wahl ist und worauf bei der jeweiligen Variablen-Konfiguration zu achten ist.
| Ebene | Sichtbarkeit | Typischer Einsatz | Variablen-Empfehlung |
|---|---|---|---|
| Shared Runner | Alle Projekte der Instanz | Lint, Unit-Tests, unkritische Jobs | Nur nicht-sensible Werte, kein Deploy-Token |
| Group Runner | Gruppe und Untergruppen | Build-Jobs, Staging-Deploys eines Teams | Group-Variablen mit Protected fuer geschuetzte Branches |
| Project Runner | Ein einzelnes Projekt | Produktions-Deploys, sensible Netzwerke | Project-Variablen, Masked und Protected zwingend |
| Variablen-Review | Quartalsweise | Alle Ebenen pruefen | Ungenutzte Variablen entfernen, Description pflegen |
Mironsoft
CI/CD-Pipelines, Zero-Downtime-Deployments und Release-Automatisierung
Deployments, die ohne Ausfallzeit und ohne Nervenkitzel laufen?
Wir prüfen bestehende GitLab-Pipelines auf fragile Deployment-Schritte und fehlende Absicherung und bauen daraus einen Release-Prozess mit Zero-Downtime-Deployments, automatisierten Checks und einem Rollback, dem ihr im Ernstfall vertrauen könnt.
Pipeline-Review
Bestehende .gitlab-ci.yml auf Fragilität, fehlende Stages und Sicherheitslücken prüfen.
Zero-Downtime-Deployment
Symlink-Releases, Health-Checks und Rollback-Strategien für Magento-Shops aufbauen.
CI/CD-Automatisierung
Tests, Security-Scans und Deployments zu einer zuverlässigen Pipeline verbinden.
10. Zusammenfassung
Group-Level Variablen und Runner: Das Wichtigste auf einen Blick
Group-Variablen
Einmal auf Gruppenebene definiert, automatisch an alle Projekte und Untergruppen vererbt.
Prioritaet
Projekt-Variable schlaegt Untergruppe schlaegt oberste Gruppe bei gleichem Namen.
Runner-Wahl
Shared fuer Masse, Group fuer Teams, Project fuer isolierte Produktions-Deploys.
Hygiene
Praefixe, Description-Feld und regelmaessige Reviews verhindern toten Variablen-Ballast.