Microsoft unterscheidet bei Azure Pipelines zwischen Microsoft-gehosteten und selbstverwalteten Agenten; diese Trennung ist die wichtigste Ausgangsentscheidung für den Betrieb eines Azure DevOps macOS Agent. Für gewöhnliche Projekte sollte zunächst ein gehosteter macOS-Agent geprüft werden. Erst wenn eine Pipeline dauerhaft dieselbe Xcode-Umgebung, persistente Caches, interne Netzwerkzugriffe oder ein kontrolliertes Schlüsselbund benötigt, lohnt sich ein eigener Agent auf einem Remote-Mac. Der Status „Online“ beweist dabei nur die Registrierung — produktionsbereit ist der Knoten erst nach einem echten Build, einem Neustarttest und einer Prüfung der Signaturdaten.
Diese Anleitung ist für drei Gruppen gedacht:
- Entwickler, die mit Azure Pipelines iOS- oder macOS-Anwendungen bauen und testen.
- DevOps-Engineers, die einen dauerhaft verfügbaren Remote-Mac in einen eigenen Agent Pool aufnehmen müssen.
- Plattformverantwortliche, die Zertifikate, Provisioning-Profile, Veröffentlichungsrechte und Arbeitsverzeichnisse voneinander trennen wollen.
Einsatzentscheidung vor der Registrierung
Ein selbstverwalteter Agent übernimmt nicht automatisch alle Aufgaben besser. Microsoft beschreibt den Unterschied zwischen gehosteten und selbstverwalteten Agenten in der offiziellen Übersicht zu Azure-Pipelines-Agenten. Daraus ergibt sich eine klare Grenze:
Ein gehosteter Agent ist normalerweise die bessere Wahl, wenn der Build mit einer dokumentierten Toolchain auskommt, keine internen Systeme erreichen muss und vertrauliche Arbeitsdaten nicht auf einem dauerhaft wiederverwendeten Rechner liegen sollen. Microsoft weist bei gehosteten Agenten außerdem auf die isolierte Ausführung und die frische Umgebung für Jobs hin; Details beschreibt die Dokumentation zu Microsoft-gehosteten Agenten.
Ein Remote-Mac als selbstverwalteter Agent ist dagegen begründbar, wenn mindestens eine der folgenden Bedingungen erfüllt ist:
- Die Pipeline benötigt eine festgelegte Xcode-Version oder zusätzliche lokale Werkzeuge, die im gehosteten Image nicht verlässlich verfügbar sind.
- Große Abhängigkeiten, Simulator-Daten oder Build-Artefakte sollen zwischen Läufen erhalten bleiben.
- Der Build muss auf interne Paketquellen, Testsysteme, Datenbanken oder ein geschütztes Netzwerk zugreifen.
- Die Signatur soll in einem kontrollierten macOS-Schlüsselbund erfolgen, dessen Zugriff nur ein bestimmter Agent erhält.
- Ein Team braucht einen dauerhaft reservierten Apple-Silicon-Knoten statt einer wechselnden Umgebung.
Nicht vertrauenswürdiger externer Code sollte hingegen nicht einfach auf einem gemeinsam genutzten selbstverwalteten Rechner laufen. Die Sicherheitsempfehlungen für Azure Pipelines sind hier die maßgebliche Referenz: Berechtigungen, Geheimnisse, Agent-Zugriff und Projektgrenzen müssen gemeinsam betrachtet werden.
Bedingte Entscheidungsliste
- Wenn nur ein reproduzierbarer Standard-Build ohne internes Netzwerk und ohne dauerhaften Cache erforderlich ist, wählen Sie zunächst einen gehosteten macOS-Agenten.
- Wenn eine feste Xcode-Installation, ein lokaler Cache oder ein privater Netzwerkpfad erforderlich ist, wählen Sie einen eigenen Agent Pool mit Remote-Mac.
- Wenn der Job fremden oder nicht geprüften Code ausführt, fallen Sie zurück auf eine stärker isolierte, gehostete Umgebung oder einen vollständig getrennten selbstverwalteten Knoten.
- Wenn Zertifikate dauerhaft auf dem Rechner verbleiben müssen, wählen Sie einen dedizierten Pool und vermeiden Sie die gemeinsame Nutzung durch unverbundene Projekte.
- Wenn nach einem Neustart keine belastbare Wiederherstellung möglich ist, geben Sie den Knoten nicht für Produktion frei.
Kosten- und Betriebsprofil der beiden Wege
Der relevante Vergleich besteht nicht nur aus der sichtbaren Miet- oder Infrastrukturrechnung. Ein selbstverwalteter Agent bringt Pflegeaufwand für macOS, Xcode, Arbeitsverzeichnisse, Zugriffsrechte, Zertifikate und Wiederherstellung mit. Ein gehosteter Agent spart diese Aufgaben, bietet aber weniger Kontrolle über lokale Zustände.
| Entscheidungspunkt | Gehosteter macOS-Agent | Remote-Mac als selbstverwalteter Agent |
|---|---|---|
| Toolchain | Vorgegebene oder vom Dienst angebotene Umgebung | Vollständig durch das Team kontrollierbar |
| Cache | Für den jeweiligen Lauf beziehungsweise die bereitgestellte Umgebung planen | Zwischen Läufen möglich, muss aber bereinigt und überwacht werden |
| Internes Netzwerk | Nur nach den jeweiligen Dienstbedingungen und Netzwerkmöglichkeiten | Direkter kontrollierbarer Netzwerkpfad möglich |
| Schlüsselbund | Kurzlebige oder pipelinegesteuerte Signatur bevorzugen | Lokaler Schlüsselbund möglich, aber mit höherem Schutzbedarf |
| Wartung | Plattformbetreiber aktualisiert die Agent-Umgebung | Team oder Dienstverantwortlicher pflegt macOS, Xcode und Agent |
| Fehlersuche | Weniger Einblick in den Host | Vollständiger SSH-Zugriff und lokale Diagnose möglich |
| Isolation | Für nicht vertrauenswürdige Jobs meist einfacher | Pool-, Konto- und Projekttrennung muss aktiv umgesetzt werden |
Für die Auswahl einer geeigneten Remote-Mac-Konfiguration und Mietlaufzeit sollte das Team deshalb nicht nur die Build-Minuten betrachten. Entscheidend sind die Kosten eines fehlenden Caches, blockierter interner Abhängigkeiten und manueller Signaturfehler ebenso wie die Verantwortung für Updates.
Registrierungsumgebung mit eigenem Konto
Ein Azure DevOps macOS Agent sollte nicht unter einem persönlichen Administratorkonto betrieben werden. Für die Registrierung wird zunächst ein eigenes lokales macOS-Konto mit möglichst geringer Berechtigung angelegt. Administrative Rechte dürfen nur für Installations- und Wartungsaktionen erforderlich sein; der normale Pipeline-Prozess sollte mit dem Agent-Konto laufen.
Danach erhält der Agent Pool eine eigene Zuständigkeit. Sinnvoll sind ein sprechender Poolname wie <POOL_NAME>, ein eindeutiger Agentname wie <AGENT_NAME> und ein festgelegtes Arbeitsverzeichnis wie <AGENT_WORK_DIRECTORY>. Echte Organisationsnamen, Tokens, Pfade und Zertifikatsbezeichnungen gehören nicht in eine öffentliche Dokumentation oder in das Repository.
Die Registrierung erfolgt nach dem aktuellen Dialog in Azure DevOps:
- Öffnen Sie die Organisation und das Projekt, in dem der Agent verwendet werden soll.
- Legen Sie einen eigenen Agent Pool an oder wählen Sie einen bereits ausdrücklich dafür vorgesehenen Pool.
- Erzeugen Sie im macOS-Agent-Dialog die Anweisungen für Betriebssystem, Pool und gewünschte Authentifizierung.
- Melden Sie sich per SSH mit dem dedizierten lokalen Konto am Remote-Mac an.
- Laden Sie das von der Konsole angebotene Agent-Paket herunter und entpacken Sie es in
<AGENT_DIRECTORY>. - Führen Sie ausschließlich den aktuell von Azure DevOps erzeugten Konfigurationsaufruf aus; Platzhalter wie
<ORGANIZATION_URL>,<POOL_NAME>,<AGENT_NAME>,<AUTH_METHOD>und<TOKEN>bleiben projektspezifisch. - Prüfen Sie im Pool den Agentnamen, den Verbindungsstatus und die gemeldeten Capabilities.
Microsoft dokumentiert mehrere Authentifizierungsoptionen, deren Verfügbarkeit und empfohlene Nutzung von der aktuellen Azure-DevOps-Konfiguration abhängen. Deshalb sollte kein dauerhaft gültiger Token in ein Skript, ein Ticket oder eine Shell-History kopiert werden. Die offizielle Übersicht zu Agent-Authentifizierungsoptionen ist vor jeder Neuinstallation zu prüfen.
Achtung: „Online“ ist lediglich ein Registrierungs- und Erreichbarkeitsnachweis. Erst wenn ein Pipeline-Lauf den richtigen Pool erreicht, ein Build erfolgreich endet und der Knoten einen Neustart übersteht, ist die Registrierung technisch belastbar.
Die erste Abnahme besteht aus einer kurzen, dokumentierten Checkliste:
- [ ] Der Agent erscheint im vorgesehenen Pool und nicht im Standardpool.
- [ ] Der Agentname lässt sich eindeutig dem Remote-Mac zuordnen.
- [ ] Das Agent-Konto besitzt keine unnötigen Projekt- oder Systemrechte.
- [ ] Die erwarteten Capabilities werden angezeigt.
- [ ] Ein Testlauf kann den Agent anhand seiner Pool-Zuordnung erreichen.
- [ ] Authentifizierungsdaten liegen nicht im Quellcode oder in gewöhnlichen Pipeline-Variablen.
Dauerbetrieb und macOS-Sitzungen
Ein reiner Kommandozeilen-Build braucht eine andere Betriebsform als ein Simulator- oder UI-Test. Für xcodebuild, Paketauflösung und Skripte reicht häufig ein Agent-Prozess ohne sichtbare Benutzeroberfläche. Simulatoren, UI-Tests und manche Schlüsselbundaktionen können dagegen eine aktive macOS-Benutzersitzung, eine grafische Umgebung oder korrekt gesetzte Sitzungsrechte voraussetzen.
Die macOS-Dokumentation von Microsoft beschreibt die Einrichtung des Agent-Dienstes mit svc.sh; dort finden sich auch die passenden Befehle für Installation, Start, Statusprüfung und Entfernung. Maßgeblich ist die aktuelle Anleitung für macOS-Agenten.
Die praktische Prüfung sollte in dieser Reihenfolge erfolgen:
- Melden Sie sich per SSH am dedizierten Konto an und wechseln Sie in
<AGENT_DIRECTORY>. - Prüfen Sie den Dienst mit
./svc.sh status. - Starten Sie ihn bei Bedarf mit
./svc.sh start. - Führen Sie einen kleinen Pipeline-Job aus, der nur Agent-Identität, Arbeitsverzeichnis und Shell-Umgebung protokolliert.
- Beenden Sie die SSH-Sitzung und wiederholen Sie den Lauf.
- Trennen Sie eine grafische Remote-Sitzung, falls UI-Tests vorgesehen sind, und prüfen Sie deren Verhalten separat.
- Starten Sie den Mac neu und kontrollieren Sie nach dem Booten den Dienststatus sowie einen vollständigen Testlauf.
Ein launchd-basierter LaunchAgent kann für Prozesse sinnvoll sein, die an eine Benutzeranmeldung gebunden sind. Er ersetzt jedoch nicht automatisch die korrekte Dienstkonfiguration für einen Hintergrund-Agenten. Die Entscheidung muss aus dem Testfall entstehen: Ein CLI-Build darf nicht unbemerkt von einer offenen SSH-Sitzung abhängen, während ein UI-Test nicht einfach als unsichtbarer Hintergrundprozess behandelt werden darf.
Xcode-Fähigkeiten und Pipeline-Routing
Azure Pipelines entscheidet anhand von Pool und Anforderungen, welcher Agent einen Job erhält. Die Grundlagen für diese Zuordnung beschreibt Microsoft in der Dokumentation zu Pipeline-Läufen und Agent-Matching. Ein vorhandener macOS-Agent genügt daher nicht, wenn die Pipeline eine bestimmte Capability erwartet.
Für die technische Erstprüfung gehören mindestens diese Befehle in einen kontrollierten Testschritt:
xcode-select -p
xcodebuild -version
xcodebuild -showsdks
Die Befehle prüfen den aktiven Entwicklerpfad, die installierte Xcode-Umgebung und die verfügbaren SDKs. Die Referenz zu den Xcode-Kommandozeilenwerkzeugen stellt Apple in der Dokumentation zu Xcode Command Line Tools bereit. Versionswerte sollten im Abnahmeprotokoll mit dem tatsächlichen Ausführungsdatum festgehalten werden, statt sie als dauerhafte Systemeigenschaft zu behandeln.
Wenn Azure Pipelines keinen Agenten mit Xcode-Fähigkeit findet, liegen typische Ursachen in einer falschen Pool-Zuordnung, einem veralteten Agent-Prozess oder einem fehlenden beziehungsweise falsch erkannten Capability-Wert. Nach der Installation, Entfernung oder Umschaltung einer Xcode-Version muss der Agent neu gestartet und die Capabilities erneut kontrolliert werden.
Für den Test empfiehlt sich ein möglichst kleines Projekt:
- Erstellen Sie ein reproduzierbares iOS- oder macOS-Testprojekt.
- Prüfen Sie, dass das relevante Scheme als „Shared“ gespeichert ist.
- Lassen Sie zunächst einen Build ohne Signierung laufen.
- Führen Sie anschließend einen Testlauf mit explizitem Simulatorziel aus, sofern UI- oder Simulator-Tests erforderlich sind.
- Kontrollieren Sie Testbericht, Exit-Status und erzeugtes Artefakt.
- Ergänzen Sie erst danach die Pool-Demands, beispielsweise für
<REQUIRED_XCODE_CAPABILITY>. - Wiederholen Sie denselben Lauf nach einem Agent-Neustart.
Der Unterschied zwischen einem erfolgreichen lokalen Befehl und einem erfolgreichen Azure-Pipelines-Lauf ist wesentlich: Erst der Pipeline-Lauf beweist, dass Pool, Demand, Umgebungsvariablen, Arbeitsverzeichnis und Artefaktablage zusammenpassen.
Signierung und Veröffentlichungsrechte
Apple-Plattform-Builds müssen in zwei getrennte Prüfpfade aufgeteilt werden: ein nicht signierter technischer Build und ein kontrollierter signierter Archiv- beziehungsweise Veröffentlichungsprozess. So lässt sich feststellen, ob ein Fehler aus Xcode, Abhängigkeiten oder aus Zertifikaten und Provisioning-Profilen stammt.
Azure Pipelines Secure Files sind für Dateien mit besonderem Schutzbedarf vorgesehen. Die offizielle Secure-Files-Dokumentation erklärt die Ablage und Autorisierung. Für Apple-Signierung sollte das Team Zertifikate und Provisioning-Profile nicht als normale Repository-Dateien und nicht als frei lesbare Pipeline-Variablen behandeln. Die konkrete Aufgabenfolge kann sich ändern; die aktuelle Anleitung zur Apple-Plattform-Signierung in Azure Pipelines bleibt deshalb die Referenz.
Die Abnahme wird in drei Stufen durchgeführt:
- Ohne Signierung: Das Projekt kompiliert mit deaktivierter Signaturprüfung beziehungsweise einer entsprechend konfigurierten Build-Variante. Dabei werden Xcode-Pfad, Dependencies und Artefakte isoliert geprüft.
- Kontrollierte Archivierung: Secure Files werden nur in dem Job geladen, der sie benötigt. Das Zertifikat wird in einen vorgesehenen Schlüsselbund importiert, der Zugriff wird auf das Agent-Konto beschränkt und das Archiv wird erzeugt.
- Bereinigung: Nach dem Lauf werden temporäre Schlüsselbundinhalte, Profile, Exportoptionen und Zwischenartefakte entfernt oder ihre Lebensdauer kontrolliert. Ein Folgejob darf keine Signaturdatei aus einem früheren Projekt vorfinden.
Bei mehreren Projekten sollte ein nicht signierender Pool von einem signierenden Pool getrennt werden. Das erschwert zwar die Auslastungsplanung, verhindert aber, dass ein gewöhnlicher Build unnötig in die Nähe von Veröffentlichungsrechten gelangt. Zusätzlich müssen Projektberechtigungen, Secure-Files-Autorisierung und lokale macOS-Rechte zusammenpassen; eine einzelne Pipeline-Berechtigung ersetzt keine Host-Isolation.
Arbeitsverzeichnisse, Caches und Wiederherstellung
Ein dauerhaft laufender Remote-Mac wird mit jedem Pipeline-Lauf zu einem Zustandsspeicher. Genau darin liegt sein Nutzen und sein Risiko. Caches können Builds beschleunigen, aber beschädigte Abhängigkeiten, alte Derived Data oder liegengebliebene Profile können spätere Projekte beeinflussen.
Vor der Freigabe sollte das Team festlegen:
- Welche Verzeichnisse zwischen Läufen erhalten bleiben dürfen.
- Welche Arbeitsordner nach jedem Job gelöscht werden.
- Ob parallele Jobs auf demselben Agent ausgeschlossen sind.
- Wie große Artefakte und Simulator-Daten erkannt werden.
- Wer macOS-, Xcode- und Agent-Updates plant.
- Wie ein fehlgeschlagener Lauf auf einem sauberen Arbeitsverzeichnis wiederholt wird.
Die Pipeline sollte nicht allein auf einem dauerhaft warmen Cache beruhen. Ein regelmäßiger Clean-Build oder ein bewusst leerer Testlauf zeigt, ob die Abhängigkeiten vollständig deklariert sind. Bleibt ein Build nur mit alten lokalen Dateien erfolgreich, ist der Knoten nicht reproduzierbar genug für eine gemeinsame Plattform.
Erfahrung aus der Betriebsprüfung: Ein schneller grüner Lauf kann ein verschmutztes Arbeitsverzeichnis verdecken. Für die Freigabe zählt daher mindestens ein erfolgreicher Lauf nach Bereinigung, ein Lauf nach Neustart und ein Lauf mit absichtlich fehlendem Cache.
Die abschließende Checkliste sollte den realen Betrieb abbilden:
- [ ] Zwei aufeinanderfolgende Jobs verwenden die erwartete Pool-Zuordnung.
- [ ] Ein fehlgeschlagener Job hinterlässt keine Signaturdaten für das nächste Projekt.
- [ ] Ein Clean-Build funktioniert ohne implizite Dateien aus einem alten Arbeitsverzeichnis.
- [ ] Ein Systemneustart bringt den Agent-Dienst ohne manuelle SSH-Anmeldung zurück.
- [ ] Ein Agent-Update wird in einer Testpipeline überprüft, bevor der Produktionspool folgt.
- [ ] Disk-Wachstum, Arbeitsordner und Cache-Löschung sind einer verantwortlichen Person zugeordnet.
- [ ] Ein Rückfall auf einen gehosteten Agenten ist für nicht signierende Jobs möglich.
Freigabe des Remote-Mac
Die endgültige Entscheidung sollte anhand von Belegen und nicht anhand des Agent-Status getroffen werden. Für die Freigabe werden Registrierung, Capability-Routing, Xcode-Build, Testbericht, Artefakt, Signaturisolierung, Bereinigung und Neustartwiederherstellung als getrennte Nachweise gespeichert.
Ein Remote-Mac ist damit eine gute langfristige Lösung, wenn feste Xcode-Werkzeuge, interne Dienste und kontrollierte Schlüsselbundrechte regelmäßig benötigt werden. Für sporadische Standard-Builds bleibt ein gehosteter Agent meist die einfachere Betriebsform. Das Team sollte außerdem festhalten, ob physische Schnittstellen, lokale USB-Geräte oder besondere Netzwerkregeln notwendig sind — solche Anforderungen können gegen eine reine Remote-Lösung sprechen.
Im Vergleich zu einem eigenen Mac mini vor Ort entfallen bei einem gemieteten Remote-Mac die Beschaffung, die anfängliche Kapitalbindung und ein Teil der lokalen Strom-, Netzwerk- und Austauschlogistik. Ein lokaler Mac mini bietet dafür unmittelbaren Gerätezugriff und kann bei langfristiger, gleichmäßiger Auslastung wirtschaftlicher sein. Ein gewöhnlicher Linux-Server oder eine virtuelle macOS-Umgebung scheitert häufig an Apple-spezifischer Toolchain, Signierung, Simulatorverhalten oder der gewünschten Hardware-Nähe. Wenn die Anwendung einen echten macOS-Knoten mit fester Umgebung braucht, aber kein physischer Kauf gewünscht ist, kann RUVCLOUD als Remote-Mac-Arbeitsumgebung die passendere Zwischenlösung sein.
Nach dem bestandenen Minimaltest sollte das Team die Mietlaufzeit und den passenden Remote-Mac-Betriebsrahmen anhand von Xcode-Fixierung, Dauerbetrieb und Berechtigungsisolation auswählen. Erst danach sollte ein eigener Azure-Pipelines-Agent-Pool produktive Projekte aufnehmen.