Semesterarbeit HF

   
Titel der Semesterarbeit Ephemere Review-Umgebungen: Automatisierte Bereitstellung von AWS-Testumgebungen pro Merge Request mit GitLab CI/CD, SQS und Lambda
Name des Studenten Ramon Schmocker
Name des Studiengangs Dipl. HF Cloud-native Engineer
Semester / AbgabeDatum Semester 2 / 27.01.2027

Inhaltsverzeichnis

[TOC]



Management Summary

Abstract

Die vorliegende Semesterarbeit befasst sich mit der automatisierten Bereitstellung von kurzlebigen (ephemeren) Testumgebungen in der Amazon Web Services (AWS) Cloud. Für jeden Merge Request (MR) in GitLab soll automatisch eine eigene, isolierte Umgebung entstehen, die bei jedem neuen Commit aktualisiert und beim Merge oder Schliessen des MR wieder abgebaut wird.

Problematik

Änderungen an einer Webanwendung werden heute meist erst nach dem Merge auf einer gemeinsamen Testumgebung sichtbar. Laufen mehrere Merge Requests parallel, überschreiben sie sich dort gegenseitig, Reviewer können eine Änderung nicht isoliert ausprobieren und Fehler fallen zu spät auf. Von Hand erstellte Test-VMs werden zudem gerne vergessen und verursachen laufende Kosten.

Zielsetzung und Methodik

Ziel dieser Arbeit ist eine Lösung, welche pro Merge Request vollautomatisch eine eigene Review-Umgebung auf AWS bereitstellt, aktualisiert und wieder abbaut. Methodisch wird hierbei bewusst eine entkoppelte Architektur umgesetzt: Die GitLab-Pipeline legt nur einen Auftrag in eine SQS-FIFO-Queue, eine Lambda-Funktion (Python) setzt diesen um. Die langlebige Basis-Infrastruktur wird vollständig in Terraform beschrieben und über die Pipeline ausgerollt. Als Oberfläche dienen die bestehenden GitLab «Review Apps» (Environment, URL, Stop-Auslöser).

Ergebnisse

Durch die technische Umsetzung erhält jeder Reviewer eine eigene, isolierte Umgebung, deren URL direkt im Merge Request sichtbar ist. Parallele Merge Requests stören sich nicht mehr gegenseitig, und da jede Umgebung beim Merge oder Schliessen automatisch abgebaut wird, entstehen keine vergessenen Instanzen und damit keine unnötigen Kosten. Die Arbeit zeigt, wie FAAS und Infrastructure as Code ineinandergreifen, um einen robusten, asynchronen Bereitstellungsprozess umzusetzen.

Ist-Situation

In der aktuellen Praxis existiert genau eine gemeinsame Testumgebung. Änderungen landen dort erst, nachdem sie in den Hauptzweig gemerged wurden. Wer eine Änderung vorher ausprobieren möchte, muss sie entweder lokal starten oder sich von Hand eine Test-VM in der AWS Management Console zusammenklicken.

GitLab bietet mit «Review Apps» zwar bereits dynamische Umgebungen pro MR an, inklusive URL-Anzeige im MR und automatischem Stoppen. Review Apps steuern aber nur den Lebenszyklus in GitLab, die eigentliche Bereitstellung auf AWS fehlt.

Problemanalyse der aktuellen Situation

Die gemeinsame Testumgebung und die manuellen Test-VMs bringen folgende Probleme mit sich:

  • Gegenseitiges Überschreiben: Laufen mehrere Merge Requests parallel, überschreibt die zuletzt deployte Änderung alle anderen. Ein isoliertes Testen ist nicht möglich.
  • Späte Fehlererkennung: Da Änderungen erst nach dem Merge sichtbar werden, fallen Fehler erst auf, wenn sie bereits im Hauptzweig sind.
  • Vergessene Ressourcen: Von Hand erstellte Test-VMs werden nach dem Review gerne vergessen und verursachen laufende Kosten.
  • Fehlende Reproduzierbarkeit: Manuell erstellte Test-VMs sind «Snowflake-Server», die sich nicht identisch wiederherstellen lassen.
  • Zu weitreichende Rechte: Würde direkt aus dem CI-Job bereitgestellt, bräuchte der Runner weitreichende EC2-Rechte.

Methodik

Die Umsetzung erfolgt nach agilen Prinzipien in Anlehnung an das SCRUM-Framework mit drei Sprints. Der Product Backlog wird als GitLab Issues geführt und nach MoSCoW priorisiert. Zur Visualisierung des Arbeitsfortschritts wird das Issue Board von GitLab als Kanban-Board eingesetzt. Jeder Sprint wird mit einem Review und einer kurzen Retrospektive abgeschlossen.

Relevanz / Motivation

Relevanz Die Entwicklungsteams der Ronova arbeiten parallel an mehreren Merge Requests, teilen sich aber eine einzige Testumgebung. Damit Reviewer Änderungen isoliert und frühzeitig prüfen können, ohne dass dabei vergessene Test-VMs Kosten verursachen, ist es erforderlich, die Bereitstellung von Review-Umgebungen vollständig zu automatisieren.

Motivation Ich arbeite privat mit GitLab CI, Terraform und AWS und möchte genau diesen Workflow auch für meine eigenen Projekte nutzen. Zudem greifen hier FAAS und IaC ineinander, und asynchrone Verarbeitung, Nebenläufigkeit und Aufräumlogik sind keine Trivialität. Genau diese Herausforderung reizt mich.

Out-of-Scope

Für dieses Projekt sind folgende Punkte out of Scope:

  • Die Entwicklung einer produktiven Webanwendung (es wird nur eine kleine Demo-Anwendung als Testobjekt verwendet)
  • Produktive Umgebungen sowie Deployments in Produktion
  • Datenbanken oder persistente Daten innerhalb der Review-Umgebungen
  • Eigene Domains und TLS-Zertifikate pro Review-Umgebung
  • Andere CI/CD-Systeme als GitLab CI/CD

Projektorganisation

Name Rolle Kontaktinformationen GitLab User GitHub User
Ramon Schmocker Projektleiter [email protected] @4G0NYY @4G0NYY
Corrado ??? Fachdozent PRJ ??? @??? @???
Armin Dörzbach Fachdozent IaC & FAAS [email protected] @armindoerzbachtbz @armindoerzbachtbz
Thanam Pangri Lehrgangsleiter [email protected] @pat-teacher @pat-teacher


Technologie-Evaluierung

Projekt: Ephemere Review-Umgebungen pro Merge Request. Evaluationsgegenstand: Art der Bereitstellung aus der GitLab-Pipeline. Evaluationsdatum: 06.11.2026 Durchführende Stelle: Projektleitung


Ausgangslage

Die Pipeline muss pro Merge Request eine Umgebung anlegen, aktualisieren und abbauen. Schwierig ist dabei nicht der einzelne Aufruf von run-instances, sondern das Drumherum: Mehrere Pipelines desselben MR können gleichzeitig laufen, Jobs werden abgebrochen, und der Abbau muss auch dann greifen, wenn die Bereitstellung noch läuft. Genau an diesen Stellen unterscheiden sich die beiden Varianten.

Varianten

Variante Beschreibung
A: Direkt aus der Pipeline Der CI-Job stellt die Umgebung selbst bereit (AWS CLI oder Terraform), die Reihenfolge pro MR regelt resource_group.
B: Pipeline + SQS + Lambda Die Pipeline legt nur einen Auftrag in eine SQS-FIFO-Queue, eine Lambda-Funktion (Python) setzt ihn um.

Weitere Ansätze wurden vorab verworfen, weil sie das Kernproblem nicht besser lösen als B, aber zusätzlichen Aufwand bringen:

Ansatz Grund für den Ausschluss
Lambda direkt über API Gateway aufrufen (ohne Queue) Keine Reihenfolge pro MR, keine Deduplizierung und keine Dead-Letter-Queue. Die Lambda müsste Nebenläufigkeit selbst lösen.
AWS Step Functions als Orchestrierung Löst Wiederholungen ebenfalls, bringt aber eine weitere Zustandsmaschine ins Projekt. Für zwei Abläufe (Deploy, Destroy) überdimensioniert.

Theoretischer Hintergrund

Variante B setzt zwei Konzepte aus dem Modul FAAS um:

  • Entkopplung über eine Nachrichtenwarteschlange: Der Auftraggeber (Pipeline) und der Ausführende (Lambda) kennen sich nicht und laufen nicht gleichzeitig. Bricht die Pipeline ab, liegt der Auftrag trotzdem in der Queue und wird verarbeitet.
  • Ereignisgesteuerte, idempotente Verarbeitung: SQS stellt Nachrichten mindestens einmal zu, eine Nachricht kann also doppelt ankommen. Die Verarbeitung muss deshalb idempotent sein: Ein zweiter «deploy» für denselben MR darf keine zweite Instanz erzeugen. Das sichern drei Ebenen ab, die FIFO-Deduplizierung über die Pipeline-ID, die Message-Group pro MR (höchstens ein Auftrag pro MR gleichzeitig) und das EC2-ClientToken.

Beispiel: Ein Entwickler pusht zwei Commits kurz hintereinander. In Variante B landen zwei Aufträge in derselben Message-Group und werden strikt nacheinander verarbeitet, der zweite aktualisiert die Instanz des ersten. In Variante A sorgt resource_group zwar ebenfalls für die Reihenfolge, wird der erste Job aber während run-instances abgebrochen, weiss der zweite nichts von der halb gestarteten Instanz.

Methode: Nutzwertanalyse

Die Varianten werden mit einer Nutzwertanalyse verglichen:

  1. Kriterien festlegen und gewichten (Summe 100 %).
  2. Jede Variante pro Kriterium auf einer Skala von 1 (ungenügend) bis 5 (hervorragend) bewerten und die Bewertung begründen.
  3. Bewertung mal Gewicht ergibt den Teilnutzen, die Summe den Nutzwert.
  4. Das Ergebnis mit einer Sensitivitätsanalyse prüfen: Hält der Entscheid, wenn die unsichersten Gewichte verschoben werden?

Die vier Kriterien aus dem Einreichungsformular (Rechte, Nebenläufigkeit, Fehler, Komplexität) tragen je 20 %, zwei ergänzende Kriterien je 10 %. Die Ergebnisse der Berechtigungsprüfung (US.1) fliessen in die Bewertung ein.

Vergleichstabelle

Bewertungskriterium Gewicht A: Direkt aus der Pipeline B: Pipeline + SQS + Lambda
1. Rechte im CI (Least Privilege des Runners) 20 % 2: Runner braucht ec2:RunInstances, ec2:TerminateInstances, iam:PassRole und SSM-Rechte 4: Runner braucht nur sqs:SendMessage. Im Schulaccount nicht durchsetzbar, weil der Runner mit den Lab-Sitzungsdaten läuft (E1, E2), darum keine 5
2. Nebenläufigkeit (parallele Pipelines pro MR) 20 % 3: resource_group reiht Jobs pro Environment ein, ein abgebrochener Job kann aber eine halb erstellte Umgebung hinterlassen 5: FIFO-Message-Group pro MR, Deduplizierung über die Pipeline-ID, EC2-ClientToken gegen Doppelanlage (in US.1 geprüft)
3. Fehlerbehandlung (Wiederholung, Nachvollziehbarkeit) 20 % 2: Job schlägt fehl, Neustart von Hand, Fehler nur im Job-Log 5: Automatische Wiederholung, fehlerhafte Aufträge landen in der Dead-Letter-Queue, unabhängig vom Runner
4. Komplexität (Aufbau, Betrieb, Testbarkeit) 20 % 5: Wenige Komponenten, alles in .gitlab-ci.yml 2: Queue, DLQ, Lambda und Rückmeldung über die GitLab-API müssen gebaut und getestet werden
5. Rückmeldung im MR (URL, Status) 10 % 5: Job kennt die URL am Ende selbst, Status entspricht dem Job 3: Job endet vor der Bereitstellung, die Lambda trägt die URL nachträglich über die GitLab-API ein
6. Bezug zu den Modulzielen (FAAS, IaC) 10 % 2: Kein FAAS-Anteil 5: Lambda, Queue und IaC greifen ineinander

Gewichtete Gesamtbewertung

Lösung Nutzwert Ranking
B: Pipeline + SQS + Lambda 4,00 1. Platz
A: Direkt aus der Pipeline 3,10 2. Platz

(Berechnung B: 0,2×4 + 0,2×5 + 0,2×5 + 0,2×2 + 0,1×3 + 0,1×5 = 4,00) (Berechnung A: 0,2×2 + 0,2×3 + 0,2×2 + 0,2×5 + 0,1×5 + 0,1×2 = 3,10)

Sensitivitätsanalyse

Annahme A B Entscheid hält?
Gewichtung wie oben 3,10 4,00 Ja
Ohne Kriterium 6 (Modulbezug, das subjektivste Kriterium) 3,22 3,89 Ja
Komplexität mit 30 % statt 20 % (übrige anteilig gekürzt) 3,34 3,75 Ja
Komplexität mit 40 % statt 20 % 3,58 3,50 Nein

Der Gleichstand liegt bei rund 38 % Gewicht für die Komplexität. B ist also nur dann die bessere Wahl, wenn Robustheit wichtiger ist als ein möglichst einfacher Aufbau. Für ephemere Umgebungen trifft das zu: Eine vergessene oder doppelt gestartete Instanz kostet laufend Geld, ein komplexerer Aufbau nur einmalig Zeit.

Vorbehalte gegen Variante B

Vorbehalt Einschätzung
Mehr Komponenten, mehr Fehlerquellen Berechtigt. Wird durch definierte Robustheitstests (doppelte Nachricht, parallele Pipelines, MR geschlossen während Bereitstellung) in US.10 abgesichert.
Der Rechtevorteil gilt im Schulaccount nicht Berechtigt. Der Runner läuft mit den Lab-Sitzungsdaten (E1, E2). Der Vorteil ist architektonisch vorhanden und wird wirksam, sobald die Lösung in einem regulären Account läuft. Für den Entscheid hält B auch ohne diesen Vorteil (Kriterium 1 für beide mit 2 bewertet: A 3,10, B 3,60).
Asynchrone Rückmeldung, der Job ist grün, bevor die Umgebung läuft Teilweise entkräftet. Die URL erscheint über die GitLab-API im Environment. Fehler sind in der Dead-Letter-Queue und in CloudWatch nachvollziehbar statt im Job-Log.
Fehlersuche über mehrere Dienste Teilweise entkräftet. Jeder Auftrag trägt MR-ID und Pipeline-ID, damit lassen sich Pipeline, Nachricht, Lambda-Log und Instanz-Tags zuordnen.
Zusätzliche Kosten für SQS und Lambda Entkräftet. Pro MR fallen nur wenige Nachrichten und Aufrufe an, die Kosten sind gegenüber der EC2-Instanz vernachlässigbar. Budget-Alarm folgt mit US.12.

Erkenntnisse

  • In Semesterarbeit 1 wurde die Bereitstellung als interaktives Bash-Skript umgesetzt, das eine Person von Hand startet. Parallele Ausführbarkeit war dort mit 5 % gewichtet, der gewählte Monolith erhielt dafür nur eine 2. Hier sind parallele Pipelines der Kern des Problems, darum fällt der Entscheid anders aus.
  • Die Berechtigungsprüfung (US.1) hat die Bewertung direkt verändert: Ohne sie wäre Kriterium 1 für B mit 5 statt 4 bewertet worden.
  • Die Sensitivitätsanalyse zeigt, dass der Entscheid nicht eindeutig ist, sondern an der Gewichtung von Robustheit gegenüber Einfachheit hängt. Das wird so offen begründet.

Handlungsempfehlung

Variante B: Pipeline + SQS + Lambda wird umgesetzt. Sie ist bei Nebenläufigkeit und Fehlerbehandlung klar überlegen, also genau dort, wo ephemere Umgebungen in der Praxis scheitern (Doppelanlagen, vergessene Instanzen nach abgebrochenen Jobs). Für das weitere Vorgehen heisst das:

  1. Architektur und Abläufe (Deploy, Update, Destroy) mit US.2 festlegen, inklusive Nachrichtenformat mit MR-ID und Pipeline-ID.
  2. Die höhere Komplexität früh mit einem Durchstich (Pipeline bis Lambda) in US.4 entschärfen.
  3. Die Vorbehalte mit den Robustheitstests in US.10 überprüfen.

ADR-001: Bereitstellung über SQS und Lambda

Feld Inhalt
Status Angenommen
Datum 06.11.2026
Kontext Pro Merge Request soll eine Review-Umgebung auf AWS entstehen, aktualisiert und abgebaut werden. Parallele Pipelines für denselben MR und abgebrochene Jobs dürfen keine doppelten oder verwaisten Instanzen erzeugen.
Entscheid Die Pipeline reiht nur Aufträge (deploy, destroy) in eine SQS-FIFO-Queue ein, Message-Group ist die MR-ID. Eine Lambda (Python) setzt die Aufträge um, startet Instanzen aus dem Launch Template und meldet die URL über die GitLab-API zurück. Der Entscheid ist mit der Freigabe der Semesterarbeit durch die Expert/innen bestätigt.
Alternativen Bereitstellung direkt aus dem CI-Job mit resource_group (Variante A, 3,10 Punkte). Lambda über API Gateway und Step Functions wurden vorab verworfen.
Konsequenzen Positiv: Reihenfolge und Deduplizierung pro MR durch SQS, automatische Wiederholung und Dead-Letter-Queue, Runner braucht im Zielbild nur sqs:SendMessage. Negativ: Mehr Komponenten, die Rückmeldung an den MR ist asynchron. Im Schulaccount läuft der Runner trotzdem mit weitreichenden Lab-Rechten (E1, E2), der Rechtevorteil gilt dort nur architektonisch.


AWS-Berechtigungen

Projekt: Ephemere Review-Umgebungen pro Merge Request. Gegenstand: Berechtigungen im AWS-Schulaccount (AWS Academy Learner Lab), US.1. Prüfdatum: 06.11.2026 Durchführende Stelle: Projektleitung


Fazit

Der Schulaccount reicht für die Umsetzung, ein Wechsel auf den privaten Account (Fallback) ist nicht nötig. Alle benötigten Dienste lassen sich anlegen, ansteuern und wieder entfernen. Es gibt aber vier Einschränkungen, die Architektur und Planung beeinflussen:

# Einschränkung Auswirkung Massnahme
E1 Keine eigenen IAM-Rollen oder -Benutzer (iam:CreateRole, iam:CreateUser verweigert) Lambda, EC2 und Scheduler können keine eigene Least-Privilege-Rolle erhalten. Es gibt keinen eigenen IAM-Benutzer für den Runner, der nur sqs:SendMessage darf. Alle Dienste nutzen die vorhandene LabRole bzw. das LabInstanceProfile. Terraform liest diese per data-Quelle statt sie anzulegen. Falls die Zeit reicht, kann eine Least-Privilege-Policy im privaten Account nachgewiesen werden.
E2 Zugangsdaten sind temporäre Learner-Lab-Sitzungsdaten (Rolle voclabs) Die CI/CD-Variablen laufen mit jeder Sitzung ab und müssen von Hand erneuert werden. Der Runner hat dieselben weitreichenden Rechte wie die Projektleitung. Vor Pipeline-Läufen die Variablen AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY und AWS_SESSION_TOKEN erneuern. Im Testprotokoll und in der Betriebsdokumentation festhalten.
E3 Nur die Regionen us-east-1 und us-west-2 sind freigegeben Keine Bereitstellung in der Schweiz oder der EU. Alles läuft in us-east-1.
E4 Die Zone us-east-1e bietet keine t3-Instanzen an Ein Subnetz ohne feste Zone landet zufällig dort, run-instances schlägt dann mit Unsupported fehl. Im ersten Prüflauf ist genau das passiert. Subnetze in Terraform immer mit fester availability_zone (z.B. us-east-1a) anlegen.

Damit ist das Akzeptanzkriterium «Eine Lambda-Funktion mit eigener Rolle kann erstellt werden» nicht erfüllbar. Die Lambda läuft mit der LabRole, was für die Funktion genügt, aber das Sicherheitsziel «Least Privilege» im Schulaccount nicht durchgesetzt werden kann.

Vorgehen

Die Rechte wurden nicht aus den Policies abgelesen, sondern mit echten Aufrufen geprüft: Jede benötigte Ressource wird angelegt, benutzt und wieder gelöscht. So fallen auch Einschränkungen auf, die nicht in einer IAM-Policy stehen (z.B. E4). Das Skript ist wiederholbar und räumt auch bei einem Abbruch alles auf:

./source/permission-check/check_permissions.sh

Ein Lauf dauert rund 7 Minuten, den grössten Teil davon wartet das Skript auf die Registrierung der Instanz bei SSM und die Docker-Installation per Run Command.

Vorhandene Lab-Rolle

Eigenschaft Wert
Angemeldet als assumed-role/voclabs/<user>
Rolle für Dienste LabRole
Instanzprofil für EC2 LabInstanceProfile (enthält LabRole)
Für das Projekt relevante Vertrauensstellungen der LabRole lambda, ec2, ssm, sqs, events, scheduler, logs
Relevante verwaltete Policy AmazonSSMManagedInstanceCore, damit sich Instanzen bei SSM melden

Resultate

Stand des Prüflaufs vom 06.11.2026 in us-east-1.

Prüfung Ergebnis Aufruf / Fehler
IAM: eigene Rolle erstellen verweigert not authorized to perform: iam:CreateRole
IAM: LabRole lesen erlaubt iam get-role
IAM: LabInstanceProfile lesen erlaubt iam get-instance-profile
Region eu-central-1 nutzbar verweigert not authorized to perform: ec2:DescribeVpcs
Region us-west-2 nutzbar erlaubt ec2 describe-vpcs
S3: Bucket erstellen erlaubt s3api create-bucket
S3: Versionierung aktivieren erlaubt s3api put-bucket-versioning
S3: Verschlüsselung setzen erlaubt s3api put-bucket-encryption
S3: Public Access Block setzen erlaubt s3api put-public-access-block
S3: Objekt schreiben erlaubt s3api put-object
S3: bedingtes Schreiben (If-None-Match) erlaubt s3api put-object
S3: Versionen auflisten erlaubt s3api list-object-versions
DynamoDB: Tabelle erstellen erlaubt dynamodb create-table
SQS: FIFO Dead-Letter-Queue erstellen erlaubt sqs create-queue
SQS: FIFO-Queue mit Redrive Policy erstellen erlaubt sqs create-queue
SQS: Nachricht mit Message-Group und Dedup-ID senden erlaubt sqs send-message
SSM: SecureString schreiben erlaubt ssm put-parameter
SSM: SecureString entschlüsselt lesen erlaubt ssm get-parameter
Lambda: Funktion mit LabRole erstellen erlaubt lambda create-function
Lambda: Funktion aufrufen erlaubt lambda invoke
Lambda: Reserved Concurrency setzen erlaubt lambda put-function-concurrency
Lambda: SQS-Trigger (Event Source Mapping) erstellen erlaubt lambda create-event-source-mapping
CloudWatch Logs: Lambda-Logs lesen erlaubt logs filter-log-events
EventBridge: Schedule-Regel erstellen erlaubt events put-rule
EventBridge: Lambda als Ziel setzen erlaubt events put-targets
Lambda: Aufrufrecht für EventBridge vergeben erlaubt lambda add-permission
EventBridge Scheduler: Schedule mit LabRole erstellen erlaubt scheduler create-schedule
EC2: VPC erstellen erlaubt ec2 create-vpc
EC2: Subnetz erstellen erlaubt ec2 create-subnet
EC2: Internet Gateway erstellen erlaubt ec2 create-internet-gateway
EC2: Internet Gateway anhängen erlaubt ec2 attach-internet-gateway
EC2: Routing-Tabelle erstellen erlaubt ec2 create-route-table
EC2: Default-Route setzen erlaubt ec2 create-route
EC2: Routing-Tabelle zuordnen erlaubt ec2 associate-route-table
EC2: Public IP im Subnetz aktivieren erlaubt ec2 modify-subnet-attribute
EC2: Security Group erstellen erlaubt ec2 create-security-group
EC2: Ingress HTTP freigeben erlaubt ec2 authorize-security-group-ingress
EC2: Launch Template erstellen erlaubt ec2 create-launch-template
EC2: Instanz aus Launch Template mit ClientToken und Tags starten erlaubt ec2 run-instances
EC2: ClientToken verhindert Doppelanlage erlaubt ec2 run-instances --client-token
EC2: Instanzen per MR-Tag finden erlaubt ec2 describe-instances
SSM: Instanz meldet sich beim Agent (LabInstanceProfile) erlaubt ssm describe-instance-information
SSM: Run Command senden erlaubt ssm send-command
SSM: Run Command installiert Docker und startet Container erlaubt ssm get-command-invocation
Budgets: Budget erstellen erlaubt budgets create-budget
Cost Explorer: Kosten abfragen erlaubt ce get-cost-and-usage
CloudWatch: Billing-Alarm erstellen erlaubt cloudwatch put-metric-alarm

Bedeutung für die User Stories

User Story Benötigt Ergebnis
US.3: Terraform Remote State S3 mit Versionierung, State Locking Möglich. S3 unterstützt bedingtes Schreiben, damit reicht use_lockfile = true ohne DynamoDB. DynamoDB wäre als Alternative ebenfalls erlaubt.
US.4: Basis-Infrastruktur VPC, Subnetz, IGW, Security Group, SQS FIFO + DLQ, Lambda, Launch Template Möglich, mit LabRole statt eigenen Rollen (E1) und fester Zone (E4).
US.6: Deploy run-instances aus Launch Template, ClientToken, Tags Möglich. Ein wiederholter Aufruf mit gleichem ClientToken liefert dieselbe Instanz, es entsteht keine zweite.
US.8: Update SSM Run Command auf der Instanz Möglich. Docker installieren und einen Container starten funktioniert über AWS-RunShellScript.
US.9: Destroy Instanzen per Tag finden und terminieren Möglich.
US.10: Robustheit Dead-Letter-Queue, Reserved Concurrency Möglich.
US.11: Aufräumen EventBridge-Regel oder Scheduler mit Lambda als Ziel Möglich, der Scheduler nutzt die LabRole.
US.12: Kosten AWS Budgets, Cost Explorer Möglich. Budget, Billing-Alarm und Kostenabfrage sind erlaubt.


Architektur

Entwurf aus dem Einreichungsformular. Wird in Sprint 1 mit US.2 finalisiert.

Übersicht

graph LR
    A[GitLab MR-Pipeline] -->|sqs:SendMessage| B[SQS FIFO Queue]
    B -->|Trigger| C[Lambda Python]
    B -.->|nach Wiederholungen| D[Dead-Letter-Queue]
    C -->|RunInstances / Terminate| E[EC2 Review-Instanz]
    C -->|SSM Run Command| E
    C -->|Environment-URL| F[GitLab API]
    E -->|docker pull| G[GitLab Container Registry]

Jede Umgebung ist eine EC2-Instanz mit der Demo-Anwendung als Container, identifiziert über die Tags Projekt und MR-ID.

Lebenszyklus

Ereignis Auslöser Ablauf
MR eröffnet MR-Pipeline, Job «deploy» mit Environment review/<MR-ID> Image bauen und in die GitLab Registry pushen, Auftrag «deploy» einreihen. Die Lambda findet keine Instanz mit dem MR-Tag und startet eine neue aus dem Launch Template. Danach trägt sie die URL über die GitLab-API im Environment ein, so erscheint sie im MR.
Neuer Commit Gleiche Pipeline erneut Auftrag «deploy» mit neuem Image-Tag. Die Lambda findet die bestehende Instanz und aktualisiert sie über SSM Run Command (neues Image ziehen, Container neu starten). Instanz und URL bleiben gleich.
MR gemerged oder geschlossen Bei MR-Pipelines startet GitLab automatisch den on_stop-Job Auftrag «destroy» einreihen. Die Lambda terminiert alle Instanzen mit dem MR-Tag, auch solche, die noch starten.
Vergessen oder Fehler (Kann) auto_stop_in und zeitgesteuerte Aufräum-Lambda Entfernt Instanzen ohne aktives Environment oder älter als die TTL.

Abgrenzung Terraform

Terraform verwaltet die langlebige Basis-Infrastruktur: VPC, Subnetze, Security Groups, Queue mit Dead-Letter-Queue, IAM-Rollen, Lambdas und das Launch Template der Review-Instanzen. Die Review-Instanzen selbst sind bewusst nicht im Terraform-State. Sie leben nur Stunden bis Tage und entstehen ausschliesslich aus dem versionierten Launch Template. Ihre Konfiguration bleibt so im Code definiert, ohne dass jede Umgebung einen eigenen State braucht.

Nebenläufigkeit

Ein Tag allein verhindert keine Doppelanlage, wenn zwei Aufträge gleichzeitig laufen. Deshalb hat jeder MR eine eigene FIFO-Message-Group, die Lambda verarbeitet also pro MR höchstens einen Auftrag gleichzeitig. Doppelte Nachrichten filtert die FIFO-Deduplizierung (Pipeline-ID), zusätzlich bekommt jeder Start ein EC2-ClientToken, mit dem EC2 bei einer Wiederholung keine zweite Instanz anlegt.

Sicherheit

  • Least Privilege für IAM-Rollen, der Runner darf nur sqs:SendMessage.
  • Keine Secrets im Repository: geschützte CI/CD-Variablen, GitLab-Token im SSM Parameter Store.
  • Kein SSH, Zugriff auf die Instanzen nur über SSM. Security Groups nur HTTP/HTTPS.


Projektplanung

Backlog

Der priorisierte Backlog kann hier gefunden werden: GitLab.com | Backlog Der Backlog ist “Top-Down”, somit sind die obersten Userstories die am meisten priorisierten.

Zielsetzung

Folgende Ziele sollen im Rahmen dieses Projekts erfüllt werden:

Nr. Ziel Messkriterium Prio
Z1 Die Basis-Infrastruktur ist vollständig in Terraform beschrieben und wird über die GitLab-Pipeline ausgerollt. terraform apply auf leerem Account läuft fehlerfrei durch, terraform plan danach zeigt keine Änderungen. Muss
Z2 Ein neuer MR erhält automatisch eine eigene Umgebung. Umgebung innert 5 Minuten erreichbar, URL als Environment im MR sichtbar. Muss
Z3 Ein neuer Commit aktualisiert die bestehende Umgebung. Nach drei Commits genau eine Instanz pro MR, die neuste Version ist ausgeliefert. Muss
Z4 Merge oder Schliessen baut die Umgebung ab. Nach Merge und nach Schliessen ist jeweils keine Instanz mit dem MR-Tag mehr vorhanden. Muss
Z5 Die Verarbeitung ist robust bei Nebenläufigkeit und Fehlern. Testfälle bestanden: doppelte Nachricht, zwei gleichzeitige Pipelines für denselben MR, MR geschlossen während die Bereitstellung läuft. Fehlerhafte Aufträge landen in der Dead-Letter-Queue. Muss
Z6 Vergessene Umgebungen werden automatisch entfernt. auto_stop_in gesetzt, Aufräum-Lambda entfernt Instanzen nach max. 24 h. Kann
Z7 Die Kosten sind transparent. Kostenabschätzung pro Umgebung und Monat, AWS-Budget-Alarm aktiv. Kann

Mindestumfang: Ein vollständiger Durchlauf mit der Demo-Anwendung: MR eröffnen, Umgebung entsteht und die URL ist im MR sichtbar, ein neuer Commit aktualisiert sie, Merge oder Schliessen baut sie ab.

Story Points

Zur Schätzung des Aufwands wird die relative Schätzung mittels Story Points (Fibonacci-Folge) gewählt. Dies ermöglicht es, Komplexität, Unwägbarkeiten und den reinen Arbeitsaufwand entkoppelt von Zeitdruck zu bewerten. Eine Story mit 5 Punkten wird dabei als etwa doppelt so aufwendig/komplex wie eine Story mit 2 oder 3 Punkten eingestuft. Als Beispiel:

Story Points Komplexität Beschreibung Beispiel im Projekt
1 Trivial Minimale Änderung, kein Risiko, sofort umsetzbar. Tippfehler in der README korrigieren oder Label anpassen.
2 Einfach Standardaufgabe ohne nennenswerte logische Hürden. Berechtigungen im Schulaccount mit der AWS CLI prüfen.
3 Moderat Erfordert Recherche oder einfache Logik/Verknüpfungen. URL der Umgebung über die GitLab-API im Environment eintragen.
5 Komplex Mehrere Abhängigkeiten, Fehlerbehandlung nötig, API-Interaktion. Bestehende Instanz über SSM Run Command aktualisieren.
8 Gross Hohe Unsicherheit, umfasst mehrere Systembereiche. Erstmaliger Deploy-Ablauf (Pipeline -> SQS -> Lambda -> EC2).
13 Epic Zu umfangreich für eine einzelne User Story. “Den gesamten Lebenszyklus inkl. aller Testfälle entwickeln” -> Muss gesplittet werden!

Priorisierung mit MoSCoW

Die Userstories sowie Tasks werden anhand von MoSCoW (Must have, Should have, Could have, Won’t have) priorisiert. Dies sorgt dafür, dass die Priorisierung auf den wirklich wichtigen Aufgaben liegt und nicht für “nice-to-have”-Dinge zu viel Zeit verbraucht wird. Must entspricht dabei dem Mindestumfang (Z1 bis Z5), die Kann-Ziele (Z6, Z7) sind Could.

Releases

Es wird gleich viele Releases wie auch Sprints geben. Somit: Pro Sprint ein Release. Dies sieht ungefähr wie folgt aus:

Sprint Release genauere Bezeichnung Nutzen
1 MVP Minimal Viable Product Die Basis-Infrastruktur steht in Terraform und ein Auftrag aus der Pipeline erreicht die Lambda (Durchstich).
2 MMP Minimum Marketable Product Der Mindestumfang läuft: Ein MR erhält eine Umgebung, ein Commit aktualisiert sie, Merge oder Schliessen baut sie ab.
3 MLP Minimal Loveable Product Die Lösung ist robust bei Nebenläufigkeit und Fehlern, räumt selbst auf und die Kosten sind transparent.

Risikomanagement

Risiko W S Risikowert (W x S) Mitigationsstrategie (Vermeidung/Lösung)
Einschränkungen des Schul-AWS-Accounts (IAM-Rollen, SQS FIFO, SSM) 3 4 12 Prüfung in Woche 1 vor jeder Umsetzung. Fallback: vorhandene Rollen nutzen oder privater Account im Free Tier.
Aufwand unterschätzt (50 h neben Arbeit und Schule) 3 4 12 Mindestumfang klar abgegrenzt, Kann-Ziele erst nach lauffähigem Mindestumfang. Zeiterfassung pro Sprint.
Doppelanlage bei gleichzeitigen Aufträgen 3 3 9 FIFO-Message-Group pro MR, Deduplizierung, EC2-ClientToken, eigener Testfall.
MR geschlossen während Bereitstellung, Instanz bleibt liegen 3 3 9 FIFO-Reihenfolge, Destroy terminiert auch startende Instanzen, eigener Testfall.
Kosten durch vergessene Instanzen 3 3 9 Kleine Instanztypen, Abbau über on_stop, Aufräum-Lambda und Budget-Alarm als Kann-Ziele.
Sicherheitslücken (offene Ports, Zugangsdaten im Repo) 2 4 8 Security Groups nur HTTP/HTTPS, kein SSH, Secrets nur in geschützten Variablen bzw. Parameter Store.
Datenverlust (Lokal) 2 4 8 Tägliche Commits und Pushes in das GitLab-Repository (Versionierung als Backup).
Ausfall der Hardware (Laptop) 1 5 5 Regelmässige Sicherung der wichtigsten Konfigurationen; Nutzung von Cloud-IDE-Alternativen im Notfall.

Legende

W: Wahrscheinlichkeit (1 = unwahrscheinlich, 5 = sehr wahrscheinlich) S: Schadensausmass (1 = vernachlässigbar, 5 = kritisch für den Projektabschluss)

Risikowert: Priorisierung der Massnahmen (Hoch > 12, Mittel 6-12, Niedrig < 6)

Die Risiken werden bei jedem Sprint-Abschluss überprüft.

Kommunikation

Die Kommunikation mit den Stakeholdern findet grundsätzlich nur über MS Teams statt. Das Gitlab-Repo ist öffentlich einsehbar und kann unter diesem Link gefunden werden: Gitlab.com Die aus dem Gitlab-Repo automatisch generierte Website kann hier eingesehen werden: docs.sa2.ronova.to

Stakeholder-Analyse

Name Rolle Einstellung Einfluss Interesse
Ramon Schmocker Projektleiter / Developer Hoch Kritisch Projekt so professionell, effizient und zielstrebig wie möglich abschliessen.
Corrado ??? Fachexperte Projektmanagement Mittel Unterstützend Hilfestellung für Projektmanagement-Anliegen / Challenges.
Armin Dörzbach Fachexperte IaC & FAAS Mittel Unterstützend Hilfestellung für technische Anliegen / Challenges.
Thanam Pangri Lehrgangsleiter / Verantwortlich bei Eskalationen Niedrig Neutral Professionelle Semesterarbeit, die bezeugt dass ich befähigt bin.

Ramon Schmocker:
Kategorie: Schlüsselfigur
Strategie: Wichtig: Regeln: Kommunikation über Teams-Kanal. Projekt so ausführlich wie möglich dokumentieren und planen. Dies ist entscheidend für den Erfolg.

Corrado ???:
Kategorie: Fachexperte
Strategie: Starke Einbindung im Projektmanagement, bei Challenges nach Rat fragen. Bei Entscheidungsunsicherheit die Stakeholder miteinbeziehen.

Armin Dörzbach:
Kategorie: Fachexperte
Strategie: Sicherstellen, dass das Produkt fachgerecht programmiert ist und dass ich jede Zeile Code erklären kann. Den Architekturentscheid (ADR) frühzeitig besprechen.

Thanam Pangri:
Kategorie: Lehrgangsleiter
Strategie: Regelmässige Updates über Teams-Kanal bereitstellen. Bei Eskalationen in Absprache bleiben.



Projektzeitplanung

Projektzeitplan (Gantt)

Hier ist die Zeitliche Abfolge der Sprints und Meilensteine dargestellt:

gantt
    title Semesterarbeit: Ephemere Review-Umgebungen
    dateFormat  YYYY-MM-DD
    axisFormat  %d.%m.

    section Planung
    Initialisierung (Einreichungsformular) :done, i0, 2026-10-16, 14d
    Sprint 0 (Setup & Doku-Struktur)       :active, s0, 2026-10-30, 7d

    section Entwicklung
    Sprint 1 (MVP - Basis-Infrastruktur)   :s1, 2026-10-30, 28d
    Einzelbesprechung 1                    :milestone, e1, 2026-11-27, 0d
    Sprint 2 (MMP - Mindestumfang)         :s2, 2026-11-28, 42d
    Einzelbesprechung 2                    :milestone, e2, 2027-01-08, 0d
    Sprint 3 (MLP - Robustheit & Kann-Ziele) :s3, 2027-01-09, 17d
    Einzelbesprechung 3                    :milestone, e3, 2027-01-25, 0d

    section Abschluss
    Abgabe der Arbeit                      :milestone, m1, 2027-01-27, 0d

Sprint 1

graph TD
    %% Definition der Spalten (Subgraphs)
    subgraph "To Do"
        T1[US.0: Evaluierung der Lösungsmöglichkeiten]
        T2[US.1: Berechtigungen im AWS-Schulaccount prüfen]
        T3[US.2: Systemdesign & Architektur]
        T4[US.3: Terraform Remote State & Pipeline]
        T5[US.4: Basis-Infrastruktur in Terraform]
    end

    subgraph "In Progress"
        P1[Aktuell keine Tasks]
    end

    subgraph "Done"
        D1[Projektstruktur aufsetzen]
        D2[GitLab CI/CD für Doku]
    end

    %% Styling für die Optik
    style D1 fill:#dfd,stroke:#333
    style D2 fill:#dfd,stroke:#333

Link zum Live Issue Board auf GitLab ↗

Sprint 2

graph TD
    subgraph "To Do"
        T1[US.5: Demo-Anwendung containerisieren]
        T2[US.6: Deploy-Ablauf pro Merge Request]
        T3[US.7: URL der Umgebung im Merge Request]
        T4[US.8: Update-Ablauf bei neuem Commit]
        T5[US.9: Destroy-Ablauf bei Merge oder Schliessen]
    end

    subgraph "In Progress"
        P1[Aktuell keine Tasks]
    end

    subgraph "Done"
        D1[Noch keine Tasks]
    end

Link zum Live Issue Board auf GitLab ↗

Sprint 3

graph TD
    subgraph "To Do"
        T1[US.10: Robustheit bei Nebenläufigkeit & Fehlern]
        T2[US.11: Automatisches Aufräumen vergessener Umgebungen]
        T3[US.12: Kostentransparenz & Budget-Alarm]
        T4[US.13: Betriebsdokumentation & Übergabe]
    end

    subgraph "In Progress"
        P1[Aktuell keine Tasks]
    end

    subgraph "Done"
        D1[Noch keine Tasks]
    end

Link zum Live Issue Board auf GitLab ↗



Projektdurchführung

Zeiterfassung

Hier sind jegliche Arbeitsaufwände dieses Projekts dokumentiert.

FTE-Budget

Für diese Semesterarbeit ist ein Gesamtbudget von rund 50 Stunden (~6.25 FTE-Tage à 8 Stunden) eingeplant. Die nachfolgend dokumentierten Aufwände werden laufend gegen dieses Budget verrechnet, um den Verbrauch über die Sprints hinweg im Blick zu behalten.

Phase Zeitraum Geplanter Aufwand
Initialisierung 16.10. bis 30.10.26 3 h
Sprint 1 30.10. bis 27.11.26 16 h
Sprint 2 28.11.26 bis 08.01.27 18 h
Sprint 3 09.01. bis 25.01.27 13 h
Total   50 h

Genehmigungsverfahren (Sprint 0)

Das initiale ausfüllen, revidieren und Re-Orientieren des PKA (Semesterarbeits-Einreichungsformulars)

  • Ausfüllen des Einreichungsformulars (V1.0) ~? Stunden
  • Überarbeitung nach Feedback (V1.1) ~? Stunden

Initiales Aufsetzen des Projekts (Sprint 0)

In diesem Abschnitt ist das initiale Aufsetzen des GitLab-Repo’s sowie der Toolselektion

  • GitLab Issue Boards aufsetzen ~? Stunden
  • GitLab Repo Struktur definieren ~? Stunden
  • GitLab CI/CD Pipeline für Webpage-Docs aufsetzen ~? Stunden
  • Domainconnect für GitLab Pages ~? Stunden

Initiale Projektplanung (Sprint 0)

  • Userstories in GitLab erfassen ~? Stunden
  • Meilensteine definieren ~? Stunden
  • Grobe Roadmap erstellen ~? Stunden

Subtotal Sprint 0

Total Sprint 0: ~? Stunden



Sprint 0

  • Einreichungsformular überarbeitet anhand Feedback der Stakeholder
  • Berechtigungen im AWS-Schulaccount prüfen (Lambda-Rolle, EC2, SQS FIFO, SSM), siehe AWS-Berechtigungen
  • Userstories erstellen & priorisieren
  • Just the Docs für Dokumentation implementieren
  • GitLab Repo strukturieren
  • Backlog Priorisierung definieren
  • Template für Userstories definieren
  • Template für Tasks definieren
  • Story Points definieren
  • Stakeholder definiert
  • Ersten Sprint planen & Stakeholder informieren
  • Besprechungen vereinbaren

Retrospektive
Folgt nach Abschluss von Sprint 0.

Room for Improvement Folgt nach Abschluss von Sprint 0.



Sprint 1

Plan des ersten Sprints

Ziele dieses Sprints:

  • MVP-Release fertiggestellt zu haben
  • Alle Tasks & Userstories, welche diesem Sprint zugewiesen sind, abzuschliessen.

Für die aktuellsten Informationen:

Link zum Live Issue Board auf GitLab ↗

Aufgaben für diesen Sprint

Implementierung des ersten Sprints

Folgt während Sprint 1.

Review des ersten Sprints

Folgt nach Abschluss von Sprint 1.



Sprint 2

Plan des zweiten Sprints

Ziele dieses Sprints:

  • MMP-Release fertiggestellt zu haben
  • Alle Tasks & Userstories, welche diesem Sprint zugewiesen sind, abzuschliessen.

Für die aktuellsten Informationen:

Link zum Live Issue Board auf GitLab ↗

Aufgaben für diesen Sprint

Implementierung des zweiten Sprints

Folgt während Sprint 2.

Review des zweiten Sprints

Folgt nach Abschluss von Sprint 2.



Sprint 3

Plan des dritten Sprints

Ziele dieses Sprints:

  • MLP-Release fertiggestellt zu haben
  • Alle Tasks & Userstories, welche diesem Sprint zugewiesen sind, abzuschliessen.

Für die aktuellsten Informationen:

Link zum Live Issue Board auf GitLab ↗

Aufgaben für diesen Sprint

Implementierung des dritten Sprints

Folgt während Sprint 3.

Review des dritten Sprints

Folgt nach Abschluss von Sprint 3.



Betriebsdokumentation

Diese Betriebsdokumentation richtet sich an das Betriebsteam der Ronova, welches die Review-Umgebungen betreibt.

Folgt in Sprint 3 (US.13).



Ergebnisse & Analyse

Folgt nach Abschluss von Sprint 3: Soll/Ist-Vergleich der Ziele Z1 bis Z7, Lieferumfang und Aufwand.



Fazit & Ausblick

Folgt nach Abschluss von Sprint 3.




This site uses Just the Docs, a documentation theme for Jekyll.