Cloud ist mehr als nur ein Ort, wo wir unsere Anwendung laufen lassen können. Die Cloud stellt auch eine API dar, die wie jede andere Schnittstelle aus unseren Anwendungen heraus aufgerufen werden kann. So lassen sich etwa zur Laufzeit virtuelle Maschinen, Datenbanken oder eben beliebige andere Cloud-Ressourcen erstellen und verwalten. Wir schauen uns in diesem Artikel die Verwendung von Cloud-APIs zur Umsetzung von Mandantenfähigkeit in Anwendungen an.
Wir haben in diesem Blog schon oft über Deployment in der Cloud geredet – entweder händisch oder besser noch mit Infrastructure as Code. Oft reicht es auch, Ressourcen statisch zu erzeugen, also einmalig vor Bereitstellung der Anwendung. So richtig viel Dynamik existiert im Bereich der Infrastruktur häufig einfach nicht – mal von Mechanismen automatischer Skalierung abgesehen.
Praktisch jede Ressource in der Cloud – und das gilt für alle größeren Cloud-Anbieter – kann jedoch auch via API dynamisch erstellt und verwaltet werden. Diese Art von Interaktion wird oft auch als programmatischer Zugriff auf die Cloud bezeichnet. Unsere Anwendung kann so Ressourcen zur Laufzeit erstellen, verändern und wieder löschen. Jede Art von Ressource lässt sich via API steuern, seien es Maschinen, Datenbanken oder beliebige andere Komponenten.
Zwar benötigen nicht alle Anwendungen einen solchen Grad an Dynamik, dennoch eröffnet der programmatische Zugriff auf die Cloud durchaus neue Möglichkeiten.
Da diese Art von Dynamik im eigenen Rechenzentrum nie oder nur eingeschränkt möglich war, kommt die Verwendung der Cloud als API in heutigen Anwendungen aber noch nicht allzu oft zum Einsatz.
Ein durchaus passender Kandidat für die Verwendung der Cloud-API hingegen ist Mandantenfähigkeit. Also die Fähigkeit innerhalb einer Anwendung, mehrere Kunden – Mandanten eben – zu verwalten; idealerweise so, dass diese Mandanten weitestgehend isoliert voneinander koexistieren können. Gleichzeitig geht Mandantenfähigkeit auch über die übliche Benutzerverwaltung hinaus, da jeder Mandant möglicherweise selbst eigene Benutzer verwalten kann; eine reine Lösung zur Verwaltung von Benutzern ist also nicht ausreichend.
Bevor wir uns anschauen, wie uns der programmatische Zugriff auf die Cloud bei der Umsetzung von Mandantenfähigkeit helfen kann, werfen wir einen Blick darauf, welche Ansätze zur Unterstützung von mehreren Mandanten üblicherweise zum Einsatz kommen.
Welcher Ansatz der richtige ist, hängt mindestens davon ab, welche Isolation zwischen den Mandanten gewünscht ist und wie einfach das Einpflegen neuer Mandanten sein soll. Letzteres wird auch gerne als Onboarding bezeichnet – durchaus ein Hinweis auf den oft manuellen Aufwand, der damit verbunden ist.
Hohe Isolation und einfaches Onboarding verhalten sich durchaus konträr. Bei einer hohen Isolation erfolgt eine recht strikte Trennung, etwa indem jedem Mandant eine dedizierte Datenbank zugewiesen wird. In der extremsten Form sind alle Ressourcen, also auch die Maschine, auf der die Anwendung läuft, getrennt. Hier wird dann nicht mehr strikt von Mandantenfähigkeit gesprochen, da das Onboarding neuer Mandanten eine komplette Spiegelung der Infrastruktur bedeutet. Hohe Isolation im eigenen Rechenzentrums ist oft gleichbedeutend mit manuellen und damit fehleranfälligen Prozessen, wie etwa der Einrichtung einer neuen Maschine und der Konfiguration einer Datenbank.
Soll das Einpflegen neuer Mandanten möglichst einfach und schnell gehen, wird oft auf ein gewisses Maß an Isolation verzichtet. Statt einer eigenen Datenbank oder gar eigener Maschinen werden die Daten innerhalb einer Datenbank durch mandantenspezifische Schemata von anderen Mandanten abgeschirmt. Im einfachsten Fall werden die Daten sogar innerhalb eines Schemas gespeichert und lediglich anhand einer Mandanten-ID unterschieden. Anders als bei höherer Isolation lässt sich das Onboarding neuer Mandanten so deutlich einfacher (voll)automatisieren.
Hohe Isolation kombiniert mit vollautomatisiertem Onboarding von Mandanten ist gewissermaßen der heilige Gral im Bereich Mandantenfähigkeit. Die Gegebenheiten im eigenen Rechenzentrum erschweren dies jedoch oder lassen es schlichtweg gar nicht zu.
Was fehlt ist nicht nur die Möglichkeit schnell neue Hardware und Software bereitzustellen, sondern dies auch mithilfe einer passenden Schnittstelle programmatisch tun zu können. Die APIs der verschiedenen Cloud-Provider hingegen bieten genau diese Möglichkeit.
Um ein automatisiertes Onboarding zu realisieren, müssen die für den Mandanten vorgesehenen Cloud-Ressourcen angelegt und diesem zugeordnet werden. Für den typischen Fall, in dem jeder Mandant seine eigene, isolierte Datenbank zugewiesen bekommt, lässt sich bei Amazon Web Service (AWS) der Code in Listing 1 als Teil des Onboarding-Prozesses verwenden. Nachdem zusätzlich die Schema-Migration erfolgt, können Anfragen des Mandanten nun durch eine geeignete Weiche auf die ihm zugewiesene Datenbank geleitet werden.
Der vergleichsweise einfache API-Aufruf führt nicht nur dazu, dass eine Datenbank erstellt wird, sondern sorgt auch automatisch für Backups und kleinere Upgrades des Datenbanksystems. Klassischerweise Themen, die bei der eigenen Implementierung von Mandantenfähigkeit händische Prozesse darstellen oder nur mit viel Aufwand automatisiert werden können.
Je nach Bedarf können weitere Operationen auf der Datenbank aus der Anwendung heraus ausgeführt werden. So könnte für Mandanten etwa die Möglichkeit geschaffen werden, zu beliebigen Zeitpunkten Backups anzulegen. Dem Mandanten könnte im Self-Service auch die Entscheidung gegeben werden, für einen Aufpreis eine leistungsstarke Datenbank zu erhalten. Alles Funktionalitäten, die zuvor meist nur außerhalb der Anwendung (händisch) abgewickelt werden konnten.
Während eine Mandanten-Datenbank naheliegend, kann in der Cloud aber noch weitergedacht werden; so können auch andere Prozesse wie etwa User-Verwaltung eines Mandanten über Bordmittel der Cloud gut isoliert werden. Cognito in AWS ist sicher ein gutes Beispiel dafür. So kann einfach eine vollständig von anderen Mandanten isolierte Benutzerverwaltung hochgefahren werden. Listing 2 zeigt exemplarisch die Erstellung einer Benutzerverwaltung für einen Mandanten; die Benutzer des Mandanten können sich dann über eine von AWS bereitgestellte Oberfläche anmelden.
Aber auch andere Ressourcen, die im Zweifel Daten des Mandanten enthalten könnten, lassen sich einfach erstellen und einem Mandanten zuweisen. So könnte ein Cache-Lösung wie Redis oder Memcached ebenfalls auf Mandanten gemünzt sein.
Insbesondere aus Gründen der Isolation sollten alle Teile der Infrastruktur, die zustandsbehaftet sind und damit sensitive Mandantendaten enthalten können, bei der Umsetzung von Mandantenfähigkeit berücksichtigt werden. Für viele dieser Teile bietet die Cloud meist durch API-steuerbare Lösungen an.
Speziell bei AWS könnte jeder Mandant sogar einen eigenen AWS-Account zugewiesen bekommen, um die Isolation noch weiter zu erhöhen; gleichzeitig wäre die Zuordnung der Cloud-Kosten zum jeweiligen Mandanten deutlich vereinfacht.
Weiter gedacht und streng nach der Definition nicht als Mandantenfähigkeit zu bezeichnen, ist die Möglichkeit, relativ einfach auch Instanzen der Anwendung dediziert für jeden Mandanten zu betreiben. Während das im eigenen Rechenzentrum mit virtuellen Maschinen durchaus bereits möglich war, bietet die Cloud hier neben anderen Ausführungsmöglichkeiten (wie etwa Lambda) auch Mittel, die im eigenen Rechenzentrum undenkbar sind.
So könnte die geographische Isolation zwischen Mandanten tatsächlich auch auf Basis des Landes, in dem Mandat ansässig ist, erfolgen. Für einen französischen Mandanten etwa könnten die relevanten Cloud-Ressourcen auch passend in Frankreich bereitgestellt werden – für deutsche Mandanten hingegen weiterhin in Deutschland. Nicht nur ist die Isolation dadurch erneut gestiegen, gleichzeitig können auch so etwaige rechtliche Voraussetzung bezüglich Datenschutz und Co. einfacher eingehalten werden. Ohne Cloud würde die Unterstützung ausländischer Mandanten die Nutzung eines anderen Rechenzentrums nach sich ziehen; häufig eine zu große Hürde.
Das Onboarding und Offboarding wären in dieser Variante Teil einer eigenständigen Anwendung, die eben die Aufgabe übernimmt, die Cloud-Ressourcen der unterschiedlichen Mandanten zu erstellen und wieder zu löschen.
Gerade Services bei Cloud-Anbietern, die ein bedarfsorientiertes Bezahlmodell haben, bieten sich für Funktionalitäten wie Mandantenfähigkeiten an. Während bei vielen Services – wie etwa einer relationalen Datenbank – Kosten auch dann entstehen, wenn diese kaum oder gar nicht genutzt werden, bieten gerade Services im Serverless-Bereich die Möglichkeit, auf Null zu skalieren – so entstehen nur dann Kosten, wenn diese auch wirklich im Einsatz sind.
Zeitgleich haben viele dieser Services ein Kostenmodell, das sich genau am Verbrauch orientiert, sodass die Kosten auch plausibel an den Mandanten weitergegeben werden können. Bei Services, die auf Basis von Maschinen abgerechnet werden, kann es sich für kleinere Mandanten mitunter nicht lohnen, größere Maschinen einzusetzen, da der Mandant im Zweifel nicht bereit wäre, die damit assoziierten Kosten zu tragen.
Dennoch könnte es gerade bei kleineren Mandanten zu Stoßzeiten zu Unzufriedenheit führen, wenn die zugewiesene Maschine nicht ausreicht. Verbrauchsorientierte Services hingegen skalieren häufig mit – ohne dabei Ressourcen-Engpässe zu rennen. Der Mandant ist dann auch durchaus bereit, diese heißen Phasen zu bezahlen, wenn dafür in ruhigen Zeiten die Kosten deutlich niedriger sind.
Die Cloud als API zu verwenden ist natürlich nicht ganz neu, denn wer bereits Cloud-spezifische Services wie etwa DynamoDB bei AWS verwendet, wird dies in der Regel bereits tun. Das Spannende ist jedoch die tatsächliche Verwaltung von Ressourcen via API – diese also nicht einfach nur zu nutzen, sondern Ressourcen auch zur Laufzeit zu erstellen, zu verändern und wieder zu löschen.
Mandantenfähigkeit – egal in welcher Ausbaustufe die Isolation umgesetzt wird – ist definitiv ein gutes Beispiel für die Möglichkeiten, die einem eröffnet werden, wenn die Cloud als API verwendet wird. Der Gedanke, zur Laufzeit mal eben eine Datenbank zu erstellen und eine Maschine samt Anwendung bereitzustellen, ist sicher vielen noch fremd. Dies ist möglicherweise auch ein Grund, warum dieser Ansatz noch nicht so oft verfolgt wird. Dennoch wird es eine Menge weiterer Anwendungsgebiete geben.
Die Cloud als API zu nutzen, um Ressourcen aus der Anwendung heraus zu verwalten, kommt natürlich auch mit einer gewissen Komplexität daher. Mit der durchaus großen Macht geht natürlich wie so häufig eine gewisse Verantwortung einher. Können die benötigten Ressourcen bereits vor Benutzung der Anwendung angelegt werden können, sollte dies auch erfolgen. Werkzeuge im Bereich Infracture as Code werden die Verwaltung von Cloud-Ressourcen üblicherweise deutlich besser beherrschen, als dies ad hoc in unserer Anwendung getan wird.
In den kommenden Wochen und Monaten erscheinen weitere Artikel zum Thema Cloud.
Was ist eigentlich aus Serverless geworden?
Low-Level- und High-Level-Cloud
Der Artikel ist Teil der IT Spektrum 05/23 S. 48
Die Vorschau des Magazins ist hier zu finden.
Wir haben in diesem Blog schon oft über Deployment in der Cloud geredet – entweder händisch oder besser noch mit Infrastructure as Code. Oft reicht es auch, Ressourcen statisch zu erzeugen, also einmalig vor Bereitstellung der Anwendung. So richtig viel Dynamik existiert im Bereich der Infrastruktur häufig einfach nicht – mal von Mechanismen automatischer Skalierung abgesehen.
Praktisch jede Ressource in der Cloud – und das gilt für alle größeren Cloud-Anbieter – kann jedoch auch via API dynamisch erstellt und verwaltet werden. Diese Art von Interaktion wird oft auch als programmatischer Zugriff auf die Cloud bezeichnet. Unsere Anwendung kann so Ressourcen zur Laufzeit erstellen, verändern und wieder löschen. Jede Art von Ressource lässt sich via API steuern, seien es Maschinen, Datenbanken oder beliebige andere Komponenten.
Zwar benötigen nicht alle Anwendungen einen solchen Grad an Dynamik, dennoch eröffnet der programmatische Zugriff auf die Cloud durchaus neue Möglichkeiten.
Da diese Art von Dynamik im eigenen Rechenzentrum nie oder nur eingeschränkt möglich war, kommt die Verwendung der Cloud als API in heutigen Anwendungen aber noch nicht allzu oft zum Einsatz.
Ein durchaus passender Kandidat für die Verwendung der Cloud-API hingegen ist Mandantenfähigkeit. Also die Fähigkeit innerhalb einer Anwendung, mehrere Kunden – Mandanten eben – zu verwalten; idealerweise so, dass diese Mandanten weitestgehend isoliert voneinander koexistieren können. Gleichzeitig geht Mandantenfähigkeit auch über die übliche Benutzerverwaltung hinaus, da jeder Mandant möglicherweise selbst eigene Benutzer verwalten kann; eine reine Lösung zur Verwaltung von Benutzern ist also nicht ausreichend.
Bevor wir uns anschauen, wie uns der programmatische Zugriff auf die Cloud bei der Umsetzung von Mandantenfähigkeit helfen kann, werfen wir einen Blick darauf, welche Ansätze zur Unterstützung von mehreren Mandanten üblicherweise zum Einsatz kommen.
Welcher Ansatz der richtige ist, hängt mindestens davon ab, welche Isolation zwischen den Mandanten gewünscht ist und wie einfach das Einpflegen neuer Mandanten sein soll. Letzteres wird auch gerne als Onboarding bezeichnet – durchaus ein Hinweis auf den oft manuellen Aufwand, der damit verbunden ist.
Hohe Isolation und einfaches Onboarding verhalten sich durchaus konträr. Bei einer hohen Isolation erfolgt eine recht strikte Trennung, etwa indem jedem Mandant eine dedizierte Datenbank zugewiesen wird. In der extremsten Form sind alle Ressourcen, also auch die Maschine, auf der die Anwendung läuft, getrennt. Hier wird dann nicht mehr strikt von Mandantenfähigkeit gesprochen, da das Onboarding neuer Mandanten eine komplette Spiegelung der Infrastruktur bedeutet. Hohe Isolation im eigenen Rechenzentrums ist oft gleichbedeutend mit manuellen und damit fehleranfälligen Prozessen, wie etwa der Einrichtung einer neuen Maschine und der Konfiguration einer Datenbank.
Soll das Einpflegen neuer Mandanten möglichst einfach und schnell gehen, wird oft auf ein gewisses Maß an Isolation verzichtet. Statt einer eigenen Datenbank oder gar eigener Maschinen werden die Daten innerhalb einer Datenbank durch mandantenspezifische Schemata von anderen Mandanten abgeschirmt. Im einfachsten Fall werden die Daten sogar innerhalb eines Schemas gespeichert und lediglich anhand einer Mandanten-ID unterschieden. Anders als bei höherer Isolation lässt sich das Onboarding neuer Mandanten so deutlich einfacher (voll)automatisieren.
Hohe Isolation kombiniert mit vollautomatisiertem Onboarding von Mandanten ist gewissermaßen der heilige Gral im Bereich Mandantenfähigkeit. Die Gegebenheiten im eigenen Rechenzentrum erschweren dies jedoch oder lassen es schlichtweg gar nicht zu.
Was fehlt ist nicht nur die Möglichkeit schnell neue Hardware und Software bereitzustellen, sondern dies auch mithilfe einer passenden Schnittstelle programmatisch tun zu können. Die APIs der verschiedenen Cloud-Provider hingegen bieten genau diese Möglichkeit.
Um ein automatisiertes Onboarding zu realisieren, müssen die für den Mandanten vorgesehenen Cloud-Ressourcen angelegt und diesem zugeordnet werden. Für den typischen Fall, in dem jeder Mandant seine eigene, isolierte Datenbank zugewiesen bekommt, lässt sich bei Amazon Web Service (AWS) der Code in Listing 1 als Teil des Onboarding-Prozesses verwenden. Nachdem zusätzlich die Schema-Migration erfolgt, können Anfragen des Mandanten nun durch eine geeignete Weiche auf die ihm zugewiesene Datenbank geleitet werden.
Der vergleichsweise einfache API-Aufruf führt nicht nur dazu, dass eine Datenbank erstellt wird, sondern sorgt auch automatisch für Backups und kleinere Upgrades des Datenbanksystems. Klassischerweise Themen, die bei der eigenen Implementierung von Mandantenfähigkeit händische Prozesse darstellen oder nur mit viel Aufwand automatisiert werden können.
Je nach Bedarf können weitere Operationen auf der Datenbank aus der Anwendung heraus ausgeführt werden. So könnte für Mandanten etwa die Möglichkeit geschaffen werden, zu beliebigen Zeitpunkten Backups anzulegen. Dem Mandanten könnte im Self-Service auch die Entscheidung gegeben werden, für einen Aufpreis eine leistungsstarke Datenbank zu erhalten. Alles Funktionalitäten, die zuvor meist nur außerhalb der Anwendung (händisch) abgewickelt werden konnten.
Während eine Mandanten-Datenbank naheliegend, kann in der Cloud aber noch weitergedacht werden; so können auch andere Prozesse wie etwa User-Verwaltung eines Mandanten über Bordmittel der Cloud gut isoliert werden. Cognito in AWS ist sicher ein gutes Beispiel dafür. So kann einfach eine vollständig von anderen Mandanten isolierte Benutzerverwaltung hochgefahren werden. Listing 2 zeigt exemplarisch die Erstellung einer Benutzerverwaltung für einen Mandanten; die Benutzer des Mandanten können sich dann über eine von AWS bereitgestellte Oberfläche anmelden.
Aber auch andere Ressourcen, die im Zweifel Daten des Mandanten enthalten könnten, lassen sich einfach erstellen und einem Mandanten zuweisen. So könnte ein Cache-Lösung wie Redis oder Memcached ebenfalls auf Mandanten gemünzt sein.
Insbesondere aus Gründen der Isolation sollten alle Teile der Infrastruktur, die zustandsbehaftet sind und damit sensitive Mandantendaten enthalten können, bei der Umsetzung von Mandantenfähigkeit berücksichtigt werden. Für viele dieser Teile bietet die Cloud meist durch API-steuerbare Lösungen an.
Speziell bei AWS könnte jeder Mandant sogar einen eigenen AWS-Account zugewiesen bekommen, um die Isolation noch weiter zu erhöhen; gleichzeitig wäre die Zuordnung der Cloud-Kosten zum jeweiligen Mandanten deutlich vereinfacht.
Weiter gedacht und streng nach der Definition nicht als Mandantenfähigkeit zu bezeichnen, ist die Möglichkeit, relativ einfach auch Instanzen der Anwendung dediziert für jeden Mandanten zu betreiben. Während das im eigenen Rechenzentrum mit virtuellen Maschinen durchaus bereits möglich war, bietet die Cloud hier neben anderen Ausführungsmöglichkeiten (wie etwa Lambda) auch Mittel, die im eigenen Rechenzentrum undenkbar sind.
So könnte die geographische Isolation zwischen Mandanten tatsächlich auch auf Basis des Landes, in dem Mandat ansässig ist, erfolgen. Für einen französischen Mandanten etwa könnten die relevanten Cloud-Ressourcen auch passend in Frankreich bereitgestellt werden – für deutsche Mandanten hingegen weiterhin in Deutschland. Nicht nur ist die Isolation dadurch erneut gestiegen, gleichzeitig können auch so etwaige rechtliche Voraussetzung bezüglich Datenschutz und Co. einfacher eingehalten werden. Ohne Cloud würde die Unterstützung ausländischer Mandanten die Nutzung eines anderen Rechenzentrums nach sich ziehen; häufig eine zu große Hürde.
Das Onboarding und Offboarding wären in dieser Variante Teil einer eigenständigen Anwendung, die eben die Aufgabe übernimmt, die Cloud-Ressourcen der unterschiedlichen Mandanten zu erstellen und wieder zu löschen.
Gerade Services bei Cloud-Anbietern, die ein bedarfsorientiertes Bezahlmodell haben, bieten sich für Funktionalitäten wie Mandantenfähigkeiten an. Während bei vielen Services – wie etwa einer relationalen Datenbank – Kosten auch dann entstehen, wenn diese kaum oder gar nicht genutzt werden, bieten gerade Services im Serverless-Bereich die Möglichkeit, auf Null zu skalieren – so entstehen nur dann Kosten, wenn diese auch wirklich im Einsatz sind.
Zeitgleich haben viele dieser Services ein Kostenmodell, das sich genau am Verbrauch orientiert, sodass die Kosten auch plausibel an den Mandanten weitergegeben werden können. Bei Services, die auf Basis von Maschinen abgerechnet werden, kann es sich für kleinere Mandanten mitunter nicht lohnen, größere Maschinen einzusetzen, da der Mandant im Zweifel nicht bereit wäre, die damit assoziierten Kosten zu tragen.
Dennoch könnte es gerade bei kleineren Mandanten zu Stoßzeiten zu Unzufriedenheit führen, wenn die zugewiesene Maschine nicht ausreicht. Verbrauchsorientierte Services hingegen skalieren häufig mit – ohne dabei Ressourcen-Engpässe zu rennen. Der Mandant ist dann auch durchaus bereit, diese heißen Phasen zu bezahlen, wenn dafür in ruhigen Zeiten die Kosten deutlich niedriger sind.
Die Cloud als API zu verwenden ist natürlich nicht ganz neu, denn wer bereits Cloud-spezifische Services wie etwa DynamoDB bei AWS verwendet, wird dies in der Regel bereits tun. Das Spannende ist jedoch die tatsächliche Verwaltung von Ressourcen via API – diese also nicht einfach nur zu nutzen, sondern Ressourcen auch zur Laufzeit zu erstellen, zu verändern und wieder zu löschen.
Mandantenfähigkeit – egal in welcher Ausbaustufe die Isolation umgesetzt wird – ist definitiv ein gutes Beispiel für die Möglichkeiten, die einem eröffnet werden, wenn die Cloud als API verwendet wird. Der Gedanke, zur Laufzeit mal eben eine Datenbank zu erstellen und eine Maschine samt Anwendung bereitzustellen, ist sicher vielen noch fremd. Dies ist möglicherweise auch ein Grund, warum dieser Ansatz noch nicht so oft verfolgt wird. Dennoch wird es eine Menge weiterer Anwendungsgebiete geben.
Die Cloud als API zu nutzen, um Ressourcen aus der Anwendung heraus zu verwalten, kommt natürlich auch mit einer gewissen Komplexität daher. Mit der durchaus großen Macht geht natürlich wie so häufig eine gewisse Verantwortung einher. Können die benötigten Ressourcen bereits vor Benutzung der Anwendung angelegt werden können, sollte dies auch erfolgen. Werkzeuge im Bereich Infracture as Code werden die Verwaltung von Cloud-Ressourcen üblicherweise deutlich besser beherrschen, als dies ad hoc in unserer Anwendung getan wird.
In den kommenden Wochen und Monaten erscheinen weitere Artikel zum Thema Cloud.
Was ist eigentlich aus Serverless geworden?
Low-Level- und High-Level-Cloud
Der Artikel ist Teil der IT Spektrum 05/23 S. 48
Die Vorschau des Magazins ist hier zu finden.