27
.
July
2022
·
14
Minuten Lesezeit

Open Thanx 2020

Wir schreiben das Jahr 2020. Moderne Softwareentwicklung unterscheidet sich heute stark von dem, was wir noch vor wenigen Jahren als State-of-the-Art gelernt haben. An die Stelle von Fat-Clients bzw. serverseitig generierten Webanwendungen, rücken modular aufgebaute, komponentenbasierte Web Anwendungen, welche auf den schier unendlich scheinenden Möglichkeiten der Browser-Runtimes aufsetzen. Single Page Applications, Progressive Web Apps, Offline-first und Web Components sind die Schlagwörter der Stunde. Das ganze natürlich auf Basis von Web Standards. Und auch das gute alte, monolithische Backend hat nicht mehr viel mit dem zu tun, was wir damals kennen und schätzen gelernt haben.

Was kommt und was bleibt in der Softwareentwicklung?

Modern Web: Trends der Webentwicklung

Die Welt rund um das Frontend befindet sich im ständigen Wandel. Die Leistung der Computer der Konsumentinnen und Konsumenten und auch deren Erwartungen an Software steigen. Während die Server von Webdiensten früher lediglich ein wenig HTML erzeugen mussten, liegt die Logik heutzutage deshalb immer mehr auf dem Client, um eine optimale User Experience sicherzustellen – und das bringt Herausforderungen mit.Im Talk schauten wir uns einige Trends der Webentwicklung an und analysierten die Probleme, die durch das Aufrüsten der Browser durch Google und Co. gelöst werden.

Slides zum Vortrag Modern Web: Trends der Webentwicklung
Slides zum Vortrag Modern Web: Trends der Webentwicklung

Q&A zu diesem Vortrag

Mich würden praktische Erfahrungen zu WebAssembly interessieren. Welche Sprachen habt ihr Konvertiert? c, c++, Go, Rust, Kotlin? Wo ging es besonders gut? Ich habe das vor ein paar Jahren mit Go versucht und das hat nicht gut funktioniert.

Da WebAssembly ein relativ junger Standard ist, halten sich natürlich unsere Erfahrungen natürlich auch, vor allem in Hinblick auf Ökosystem und Stabilität, in Grenzen. Es ist aber so, dass wir bereits mit Go erste Erfahrungen sammeln konnten. Im Hinblick auf die Frage wäre natürlich gut zu wissen was unter “nicht so gut funktioniert” zu verstehen ist. Es ist bei Go leider so, weil es eine “garbage collected” Sprache ist, dass diese eine gewisse Runtime mit sich bringt und das äußert sich auch in der große der WASM-Datei (Das, was der User am ende runterladen muss).

Auch konnten wir feststellen, dass die performance (noch) nicht mit der einer nativen Go-Binary zu vergleichen ist. Unsere unwissenschaftlichen beobachten belaufen sich hier auf einen Unterschied von ca 40 Sekunden  zu 90 Sekunden. Kompiliert wurde dabei derselbe Go-Code in WASM sowie als native binary.

Die API in Go machte auch nicht besonders große Probleme. Speziell für “go” gibt es beispielsweise das “system/js” package (https://golang.org/pkg/syscall/js/). Das Package bietet uns z.B. die Möglichkeit der JavaScript Umgebung bestimmte APIs zur Verfügung zu stellen. Das sieht dann ungefähr so aus:

 “system/js” package
 “system/js” package

Durch ein kompilieren mit bestimmten Flags, ist die Go Binary auch schnell erzeugt. Sowohl bei C als auch C++, Rust und Kotlin habe ich selbst keine Erfahrung gemacht. Von Kollegen weiß ich, dass das C++, grade aufgrund von emscripten (https://developer.mozilla.org/en-US/docs/WebAssembly/C_to_wasm) am weitesten sein soll. Das ist natürlich Fluch und Segen zugleich – es gibt nicht die eine Erfahrung mit WebAssembly aufgrund der schier unendlich unterstützten Sprachen mit ihren Eigenheiten.

Würde mich auch interessieren. Auch sowas wie Build-Management. Viele native Anwendungen werden ja z.B. mit Autotools etc. gebaut. In welchem Umfang funktioniert sowas?

In dem Hinblick kommt’s natürlich immer auf die Sprache an. Bleiben wir beispielsweise beim Go-Beispiel, dann ist das WebAssembly-Ziel bereits vorgesehen und so gesehen in das Tooling integriert. D.h. ich kann ganz normal meine Go-Utilities und dessen Techstack nutzen. Ich gehe aber davon aus, dass das stark von der Sprache abhängt. Nimmt man beispielsweise C++ als Beispiel, dann ist emscripten (https://developer.mozilla.org/en-US/docs/WebAssembly/C_to_wasm) natürlich eine andere Build-Chain als g++.

Mich würde es interessieren, wie es bzgl. der Security aussieht. Wenn der Code auf dem Client ausgeführt wird, könnte ich mir hier deutlich mehr Exploits vorstellen – vor allem im Hinblick auf die leider viel genutzten veralteten Browsern.

Generell gilt beim Browser, dass er relativ sicher ist. Das liegt sicher am Sandbox-Modell, das dieser sowohl für JavaScript als auch für WebAssembly vorsieht. Es ist aber so, dass Browser selbst auch nicht immer 100% sicher sind, wie uns Spectre (https://de.wikipedia.org/wiki/Spectre_(Sicherheitsl%C3%BCcke) gezeigt hat. Grade im Hinblick auf veraltete Browser wird es im Progressive WebApp (PWA) Aspekt sowieso sehr schwer, da die Plattform natürlich davon lebt, dass diese regelmäßig erweitert wird.

Das der Browser sicher ist, heißt aber nicht, dass unsere App sicher ist. Wir müssen uns natürlich immernoch um Dinge, wie Resource Policies, Cross Site Scripting etc. kümmern.

Wie groß werden dann solche Apps? moderne Webseiten haben schon eine absurde Größe. wenn nun noch irgendwelche runtimes angezogen werden….

Wir müssen natürlich hier erstmal unterscheiden, was “moderne Webseiten” sind. Ich interpretiere moderne Webseiten hier erstmal als “moderne Webapplikationen”, die clientseitig gerendert werden – sogenannte Single Page Applications (SPA). Es ist natürlich so, dass SPAs mit der Zeit immer mehr an Code-Größe zunehmen – und das kriegt auch der Nutzer in Form von Dateigrößen zum Downloaden zu spüren. Nach oben hin ist da keine Grenze gesetzt.

Das sind aber natürlich Probleme, für die es neben den klassischen geschenkten technischen Lösungen wie “gzipping” und “minification” bereits Lösungen gibt. Als Stichwort is hier zum Beispiel Code Splitting genannt. Beim Code Splitting kann man eben auch auf “fachliche” Modulebene, sprich z.B. Route, Bereich, Rolle o.Ä. ein Splitting vornehmen, sodass auch nur gewisse Codestücke geladen – und auch wieder verworfen werden, wenn sie nichtmehr gebraucht werden. Das führt eben dazu, dass man geladenen Code auf ein Minimum reduzieren kann.

Man muss hier aber sagen, dass das eventuell gar nicht so relevant ist. Wenn wir SPAs haben, dann sind diese in der Regel sehr gut cacheable. Wir laden dann also jeden “chunk” im besten Fall sowieso nur einmal runter. Vor allem im Hinblick auf den nächsten Step der Evolution – der Progressive WebApp (PWA).

Gehen wir den Schritt weiter zur PWA, also SPAs, die die BrowserAPIs stark in Anspruch nehmen um Werte zu generieren (Nutzung von IndexedDB, Nutzung von WebRTC etc.) und offline Fähigkeiten mitbringen, dann ist der Vorteil, dass dieselben Dinge gelten wie für SPAs (Code Splitting). Das ist ja das schöne – die APIs werden vom Browser festgelegt und müssen eben nicht implementiert, sondern bedient werden. Der Code wird ja von unserer Plattform, dem Browser, bereitgestellt. Sprich: Es hat keine Auswirkungen auf unser letztlich code-bundle.

Zu guterletzt natürlich WebAssembly binaries. Hier tut sich natürlich viel. Ich selbst kann von binaries für simples parsing von um die 20MB berichten –  das is schon sehr viel. Aber: Auch hier gilt, dass man das eben durch den Browser oder eben Service Workern gut cachen kann. Die vorgestellte AutoCAD Applikation (https://github.com/WebAssembly/design/issues/1166 )ist um die 29MB groß.

Zukunftssichere Architekturen mit Microservices

Mit dem Begriff „Microservice-Architektur“ wird der Architekturstil beschrieben, bei dem mehrere unabhängige Services eine Applikation bilden. Aber in welchen Situationen ist die Wahl dieses Ansatzes sinnvoll? Welche Konsequenzen hat es, wenn ich mich dafür entscheide? Wie finde ich den richtigen Service-Schnitt? Und wie baue ich ein passendes Frontend dazu?Der Vortrag gab einen guten Überblick über die Herausforderungen und deren Lösungsmöglichkeiten und beleuchtete dabei auch Themen wie Testing und Continuous Delivery.

Slides zum Vortrag Zukunftssichere Architekturen mit Microservices
Slides zum Vortrag Zukunftssichere Architekturen mit Microservices

Q&A zu diesem Vortrag

Zu Consumer Driven Contracts: Wie geht das am einfachsten mit einem Android/iOS Client? Wie fällt aus der App ein Testframework heraus?

Das Vorgehen bei einem Android-Client ist ähnlich wie bei einem Java-Client: Beim Tool Pact wird z.B. ein Mock-Server gestartet, dessen Verhalten im Unit-Test des Clients definiert werden kann. Dieser schreibt dann die tatsächliche Interaktion des Clients mit dem Mock-Server mit und erzeugt dadurch einen Contract, der die Interaktion widerspiegelt. Dieser kann dann über eine zentrale Stelle (z.B. einem Pact-Broker) dem Client zur Verfügung gestellt werden.

Gibt es gute pattern in einer Microservices Architektur für stark übergreifende Vorfälle, z.B. Datenlöschungswunsch eines Nutzers auf Basis einer DSGVO Anfrage?

Übergreifende Fälle wie ein Datenlöschungswunsch auf Basis einer DSGVO-Anfrage wird über Domain-Events gelöst. Dazu muss sich jeder Service bei der Messaging-Infrastruktur registrieren und auf dieses Event lauschen.

Cloud, das „New Normal“?

„Cloud is the new normal”, so Andrew R. Jassy (CIO AWS). Was also liegt näher, als genau jetzt den Schritt in die Cloud zu wagen? Denn schließlich wollen wir ja alle irgendwie ein klein wenig „normal“ sein.

Aber ist dieser Schritt wirklich so einfach, wie uns die verschiedenen Cloudanbieter glauben machen? Lässt sich eine klassische Enterprise-Architektur einfach so in die Cloud überführen oder bedarf es neuer, cloudspezifischer Architekturmuster?  Was unterscheidet dabei die verschiedenen As-a-Service-Varianten (IaaS, PaaS, BaaS und FaaS) voneinander und für welchen Anwendungsfall nimmt man was? Fragen über Fragen – aber keine Panik, der Talk lieferte Antworten.

Slides zum Vortrag Cloud Computing – Das „New Normal“?
Slides zum Vortrag Cloud Computing – Das „New Normal“?

Q&A zu diesem Vortrag

Bezüglich Cloud Maturity Model: was ist da eure Erfahrung, würdet ihr sagen es ist besser alle Stufen der Reihe nach zu durchlaufen, oder können bestimmte größere Transformatinsschritte (z.B. gleich von Ready -> Resilient oder ähnlich) gelingen? Was sind da eure Erfahrungen bisher?

Das Cloud Maturity Model ist weniger als Schritt-für-Schritt-Anleitung zu verstehen. Es dient vielmehr als eine Art Gradmesser oder Lackmustest der eigenen „Cloudability“. D.h. mit Hilfe des Cloud Maturity Models lässt sich für Unternehmen oder einzelne Projekte sehr gut abschätzen, wo man aktuell auf dem Weg hin zu Cloud native steht und welche Schritte / Aufgaben man ggf. noch vor sich hat. Auf Basis dieser Bestandsaufnahme lässt sich nun das weitere Vorgehen entscheiden.

Im weiteren Vorgehen gilt es dabei zwischen dem Nutzen von Innovation bzw. Cloud-native-Reifegrad auf der einen Seite und dem adäquaten Aufbau von Cloud-Expertise auf der anderen Seite abzuwägen. Denn ohne hinreichende Expertise wird man auf jeden Fall scheitern.

Unsere Erfahrungen in den realen Cloud-Projekten der letzten Jahre haben gezeigt, dass der Aufbau von Erfahrungen im Rahmen von PoCs, MVPs oder losgelösten Projekten und die anschließende Übertragung dieser Erfahrungen in eine allgemein gültige Cloud-Strategie und Cloud-Governance (siehe auch nächste Dragee) die schnellsten und nachhaltigsten Erfolge mit sich bringt.

Unter dem Begriff „Erfahrung“ sind dabei sowohl die Cloud-Plattform selbst, sowie das benötigtes Tooling gemeint (Technologie), als auch Fragen der Architektur und Organisation. Aber auch ganz triviale Fragestellung, wie z.B. das Entwickeln eines besseren Verständnisses für die Cloud-Kostenstrukturen des bzw. der gewählten Provider, spielen hier mit ein.

Sollte, aus welchen Gründen auch immer, zwingend eine Migration einer größeren Anwendung en-block in die Cloud notwendig sein, ist auf jeden Fall eine Schritt-für-Schritt Migration ratsam. Dabei sollte man sich aber nicht ausschließlich an den vorgegebenen Schritten des Cloud Maturity Model orientieren, sondern viel mehr schauen, wie die im Modell vorgegebenen Schritte evtl. sinnvoll – im eigenen Kontext – noch einmal weiter herunter gebrochen werden können. D.h., man würde zum Beispiel versuchen neben den ersten Teilschritten im Bereich Cloud-friendly (z.B. Skalierung und HA via Cloud, Automatisierung) parallel auch schon einmal die ersten essentiellen Schritte im Bereich Cloud-resilient (z.B. das Sammeln und Verarbeiten von Health Probe und Metriken) anzugehen.

Welche Schritte man wann genau geht, hängt stark von dem eigenen Kontext und der in der Cloud zu platzierenden Anwendung(en) bzw. Workloads ab. Hier hilft es, sich initial einen Blick zu verschaffen und eine entsprechend Cloud-Migration-Roadmap aufzusetzen, an der man sich dann im weiteren Verlauf orientieren kann. Natürlich gilt es diese Roadmap agil und iterativ, auf Basis der während der Migration gewonnenen zusätzlichen Erkenntnisse, permanent zu adaptieren.

Cloud-Transformationen sind ja recht komplex in mehreren Dimensionen (Technik, Org, Mindset, …). Würdest du da sowas wie ein „Cloud Center of Excellence“ empfehlen, oder mit welchen Begleitmaßnahmen würdest du das angehen?

Wenn nicht nur eine einzelne Anwendung sondern große Teile der Unternehmens-IT in die Cloud gehoben werden sollen, würde ich auf jeden Fall ein „Cloud Center of Excellence“ und den damit einhergehenden iterativen Aufbau einer, sich an der Cloud-Strategie orientierenden Cloud-Governance sehen.

Wichtig ist allerdings, dass sich dieses Vorgehen nicht in einem Elfenbeinturm abspielt, sondern dass das „Cloud Center of Excellence“ die Erfahrungen aus den realen Projekten aufgreift (siehe oben), bewertet und daraus verallgemeinerte Rückschlüsse für die zu entwickelnde Cloud-Governance zieht. Getreu dem Motto „aus der Praxis für die Praxis“ kommen diese dann in weiteren zukünftigen Cloud-Projekten zum Einsatz und werden dort weiter erprobt.

Aus unserer Erfahrung heraus hilft es, wenn das „Cloud Center of Excellence“ aus mindestens einem für dieses Thema dediziert bereitgestellten Mitarbeiter sowie einer Reihe von Cloud-affinen Kollegen aus den verschiedenen aktiven (Cloud-)Projekten besteht. Der dedizierte Mitarbeiter stellt sicher, dass das Thema „Cloud Excellence“ nicht im Alltagstrubel der verschiedenen Projekte untergeht – ausreichend Management Awareness vorausgesetzt!

Die Cloud-affinen Kollegen aus den verschiedenen aktiven Cloud-Projekten wiederum stellen sicher, dass die eigenen Erfahrungen und der eigene Unternehmenskontext hinreichend bei der Entwicklung der Cloud Excellence berücksichtigt wird.

Natürlich muss man hier nicht alle Erfahrungen selber machen. Mittlerweile gibt es hinreichend viele große Cloud-Projekte und Experten am Markt, die recht offen mit ihren Erfahrungen umgehen und von denen man entsprechend partizipieren kann. Trotzdem gilt es aber, auch diese Erfahrungen in den eigenen Kontext zu setzen, bevor man sie in die eigene Cloud-Governance und Cloud-Strategie einfließen lässt.

Es gibt teils Horrorstories, bei denen Bedienungsfehler effektiv ein ganzes Unternehmen gelöscht haben. Sind das Lagerfeuergeschichten und die Dienste sind inzwischen so leicht absicherbar oder ist das eine reelle Gefahr, für die man Backups außerhalb der cloud halten sollte?

Derartige Meldungen hört bzw. liesst man tatsächlich immer wieder. In der Regel stammen diese allerdings aus den Anfängen der Cloud-Historie und sind somit schon ein paar Jahre alt. Mittlerweile bieten alle Cloud-Provider hinreichend gute Sicherheitsmechanismen sowohl für Daten & Dienste, welche in der Cloud platziert werden an, als auch für die potentiell generierten Kosten an.

Allerdings greifen diese natürlich nur, wenn man sich auch an das , häufig sehr, sehr komplexe Rollen- und Rechtssystem der Cloud-Provider hält. Und genau hier liegt das Problem. Mangels eindeutiger Cloud-Strategie und Cloud-Governance erhalten einzelne Entwickler nicht selten umfangreiche Rechte auf den Cloud-Systemen, welche deutlich über das Hinausgeht, was man ihnen im eigenen Rechenzentrum zugestehen würde.

Häufig beginnt die Transition in die Cloud damit, dass ein Entwickler oder eine sehr kleine Gruppe von Entwicklern ein Unternehmens-Cloud-Account anlegt und sich selbst dann für dieses „All-In“ Rechte gibt. Dieses Vorgehen scheint in diesem Moment auch nicht weiter schlimm, da man in der Regel mit sehr kleinen MVPs in der Cloud startet. Nur leider wächst dann irgendwann der Projekt- oder Unternehmensdruck. Neuer Anforderungen werden an die Entwickler herangetragen. Weitere Projekte möchten in die Cloud und weitere Entwickler müssen entsprechend Zugänge freigeschaltet bekommen usw.

Es ist daher zwingend notwendig sich von Anfang ausgiebig mit dem Rollen- und Rechtssystem des genutzten Cloud-Providers auseinanderzusetzen und die Rechte immer nach dem Prinzip „so wenig wie möglich, so viel wie notwendig“ zu vergeben. Das gilt übrigens sowohl für die eigenen Mitarbeiter, die sich in der Cloud bewegen, als auch für die Software, sie in der Cloud lebt bzw. auf Cloud-Komponenten zugreift!

Auch bitte es sich an, den Entwicklern einen eigenen monetär und aus Sicht der zu verwendenden Ressourcen eingeschränkten Account und somit einen eigenen Playground bereitzustellen. Dies ermöglicht ihnen beliebige „Experimente“ durchzuführen ohne dabei das Unternehmens-Account weiter öffnen und somit fragiler machen zu müssen.

Multi-Cloud Stacks wie Google Anthos einsetzen oder doch lieber bei CNCF bleiben? Welchen Einfluss hat dies auf die Architektur?

Bereits bei den ersten Gehversuchen in der Cloud stellt sich die Frage, wie stark man sich auf die propritären Plattformkomponenten des einzelnen Cloud-Provider einlassen und somit ein Verdor Lock-in in Kauf nehmen soll. Diese Fragestellung gilt natürlich dann umso mehr, wenn der eigene Plan eine Multi-Cloud-Strategie vorsieht.

Eine mögliche Lösung bietet die Orientierung an den Vorschlägen der Cloud Native Computing Foundation (https://www.cncf.io) zum Aufsetzen von nachhaltigen Ökosystemen für Cloud-native Anwendungen.

Soweit, so gut. Leider bringt der vorgeschlagene Stack eine nicht unerhebliche Komplexität in der Betreuung mit sich, so dass entsprechend Mitarbeiter zunächst hinreichend gut ausgebildet werden müssen, um sie dann im Anschluss mit der permanenten Beobachtung und Verbesserung des Systems zu betreuen.

Angefangen vom Aufsetzen eine Kubernetes-Clusters, über die permanente Aktualisierung des darüber hinaus verwendeten Toolings, bis hin zur Überwachung der in dem Ökosystem laufenden Anwendungskomponenten stehen mehr als genug Aufgaben an, um den Tag gleich mehrerer Mitarbeiter zu füllen.

Nicht immer ist es möglich und/oder sinnvoll dies Arbeit wirklich im Detail selber zu vollziehen. Stattdessen bietet sich die Verwendung von entsprechenden Distributionen oder Management-Tools ab, die zum einen viele der anstehenden Aufgaben durch entsprechende Automatismen im Hintergrund erledigen bzw. durch Convenient-Schnittstellen verdichten und zum anderen eine einheitliche und deutlich besser zu handhabende Sicht auf den Zoo von Komponenten und Tools liefern. In den von uns in den letzten Jahren begleiteten Cloud-Projekten sind wir, bis auf in ganz wenigen Ausnahmen, grundsätzlich diesen weg gegangen.

Wie vorab schon bei den Cloud-Providern, stellt sich allerdings auch bei diesen Tools die Frage, wie stark man sich auf die individuellen Features der Distributionen bzw. Management Plattformen einlassen und sich somit abhängig von diesen machen möchte. Zumal man ja bewusst auf Kubernetes und Co gesetzt hat, um genau dem Dilemma der Abhängigkeit (zu einem Cloud-Provider) zu entgehen!

Aus unserer Erfahrung heraus hat sich ein hybrider Ansatz als gut erwiesen, bei dem zwar auf entsprechende Distributionen bzw. Management Plattformen zurückgegriffen wird, bei deren Verwendung aber sorgsam darauf geachtet wird, an welchen Stellen man sich von Standards bzw. de-facto Standards entfernt. Immer dann, wenn man diesen Schritt geht, sollte dies auch eine bewusste Entscheidung sein.

So lässt sich z.B. der Aufbau eines Kubernetes Clusters mit Kubernetes Bordmitteln beschreiben (also im Standard) oder aber via proprietärer und in der Regel entsprechend einfacherer Mittel. Trotzdem würden wir in diesem Fall auf die Verwendung des (de facto) Standards setzen, um dieses Herzstück unserer Cloud-Infrastruktur relativ einfach portieren zu können. Gleiches gilt z.B. für die Wahl der Monitoring-Werkzeuge, wie dem Metrik- oder das Tracing-Format (openMetrics, openTracing).

Mit Hilfe dieser kleinen Regeln lässt sich bereits ein Großteil der Vorteile der Distributionen und Management Plattformen nutzen ohne dabei eine zu starke Abhängigkeit einzugehen und sich somit zwingend an das gewählte Tooling zu binden.


Wie sind andere Kunden aus den Branchen Versicherungen/Banken in den Bereichen Web bzw. Cloud Technologien aufgestellt?

Wir, als branchenneutraler Lösungsanbieter, sehen den Trend hin zu „zeitgemäßer“ Software über all unsere Kunden und somit alle Branchen hinweg. Insbesondere Kunden mit dedizierten Kundenportalen (B2C), wie z.B. Textilhersteller, Banken oder Versicherungen aber auch Anbieter anderer Produkte (B2C & B2B), wie z.B. Logistik- oder Energie-Unternehmen, setzen bei ihren Lösungen mit immer stärker wachsender Priorität auf neue Web Technologien in Kombination mit modularen Backend Services (Software-as-a-Service) und der Cloud.

Ob man im Frontend am Ende tatsächlich alle Buzzwords, wie Single Page Applications, Progressive Web Apps, Offline-first und Web Components im Detail befriedigt oder den Anwendern einfach „nur“ eine in ihrem Kontext ergonomisch wirklich gut funktionierende Web Anwendung zur Verfügung stellt, ist dabei egal.

Das Backend muss natürlich auch nicht zwingend auf Microservices basieren. Es sollte aber zumindest so aufgebaut sein, dass neben zentralen Komponenten (z.B. in Form einer Plattform), einzelne Module, die unabhängig voneinander entwickelt und getestet werden können, die verschiednen fachlichen Bausteine der Software abbilden.

Und auch der Schritt in Richtung Cloud bedeutet nicht zwangsläufig, dass man sich auf einen der großen Player, wie AWS, Microsoft oder Google, einlassen muss. Wichtig ist vielmehr, dass man sich dem Paradigma der schnellen Provisionierung und elastischen Infrastruktur verschreibt. Egal ob in der Private oder Public Cloud.

Unsere Kunden haben verstanden, dass sie nur mittels moderner Softwaresysteme – und natürlich einer entsprechenden agilen Organisation – in der Lage sind, auf die schnelllebigen Anforderungen am Markt zu reagieren. Es geht also nicht (nur) um schicke Oberflächen und tolle Technologien sondern vor allem um Investitionen in Wettbewerbsfähigkeit und Zukunft.


Zur OPEN THANX 2021.

No items found.

Was kommt und was bleibt in der Softwareentwicklung?

Modern Web: Trends der Webentwicklung

Die Welt rund um das Frontend befindet sich im ständigen Wandel. Die Leistung der Computer der Konsumentinnen und Konsumenten und auch deren Erwartungen an Software steigen. Während die Server von Webdiensten früher lediglich ein wenig HTML erzeugen mussten, liegt die Logik heutzutage deshalb immer mehr auf dem Client, um eine optimale User Experience sicherzustellen – und das bringt Herausforderungen mit.Im Talk schauten wir uns einige Trends der Webentwicklung an und analysierten die Probleme, die durch das Aufrüsten der Browser durch Google und Co. gelöst werden.

Slides zum Vortrag Modern Web: Trends der Webentwicklung
Slides zum Vortrag Modern Web: Trends der Webentwicklung

Q&A zu diesem Vortrag

Mich würden praktische Erfahrungen zu WebAssembly interessieren. Welche Sprachen habt ihr Konvertiert? c, c++, Go, Rust, Kotlin? Wo ging es besonders gut? Ich habe das vor ein paar Jahren mit Go versucht und das hat nicht gut funktioniert.

Da WebAssembly ein relativ junger Standard ist, halten sich natürlich unsere Erfahrungen natürlich auch, vor allem in Hinblick auf Ökosystem und Stabilität, in Grenzen. Es ist aber so, dass wir bereits mit Go erste Erfahrungen sammeln konnten. Im Hinblick auf die Frage wäre natürlich gut zu wissen was unter “nicht so gut funktioniert” zu verstehen ist. Es ist bei Go leider so, weil es eine “garbage collected” Sprache ist, dass diese eine gewisse Runtime mit sich bringt und das äußert sich auch in der große der WASM-Datei (Das, was der User am ende runterladen muss).

Auch konnten wir feststellen, dass die performance (noch) nicht mit der einer nativen Go-Binary zu vergleichen ist. Unsere unwissenschaftlichen beobachten belaufen sich hier auf einen Unterschied von ca 40 Sekunden  zu 90 Sekunden. Kompiliert wurde dabei derselbe Go-Code in WASM sowie als native binary.

Die API in Go machte auch nicht besonders große Probleme. Speziell für “go” gibt es beispielsweise das “system/js” package (https://golang.org/pkg/syscall/js/). Das Package bietet uns z.B. die Möglichkeit der JavaScript Umgebung bestimmte APIs zur Verfügung zu stellen. Das sieht dann ungefähr so aus:

 “system/js” package
 “system/js” package

Durch ein kompilieren mit bestimmten Flags, ist die Go Binary auch schnell erzeugt. Sowohl bei C als auch C++, Rust und Kotlin habe ich selbst keine Erfahrung gemacht. Von Kollegen weiß ich, dass das C++, grade aufgrund von emscripten (https://developer.mozilla.org/en-US/docs/WebAssembly/C_to_wasm) am weitesten sein soll. Das ist natürlich Fluch und Segen zugleich – es gibt nicht die eine Erfahrung mit WebAssembly aufgrund der schier unendlich unterstützten Sprachen mit ihren Eigenheiten.

Würde mich auch interessieren. Auch sowas wie Build-Management. Viele native Anwendungen werden ja z.B. mit Autotools etc. gebaut. In welchem Umfang funktioniert sowas?

In dem Hinblick kommt’s natürlich immer auf die Sprache an. Bleiben wir beispielsweise beim Go-Beispiel, dann ist das WebAssembly-Ziel bereits vorgesehen und so gesehen in das Tooling integriert. D.h. ich kann ganz normal meine Go-Utilities und dessen Techstack nutzen. Ich gehe aber davon aus, dass das stark von der Sprache abhängt. Nimmt man beispielsweise C++ als Beispiel, dann ist emscripten (https://developer.mozilla.org/en-US/docs/WebAssembly/C_to_wasm) natürlich eine andere Build-Chain als g++.

Mich würde es interessieren, wie es bzgl. der Security aussieht. Wenn der Code auf dem Client ausgeführt wird, könnte ich mir hier deutlich mehr Exploits vorstellen – vor allem im Hinblick auf die leider viel genutzten veralteten Browsern.

Generell gilt beim Browser, dass er relativ sicher ist. Das liegt sicher am Sandbox-Modell, das dieser sowohl für JavaScript als auch für WebAssembly vorsieht. Es ist aber so, dass Browser selbst auch nicht immer 100% sicher sind, wie uns Spectre (https://de.wikipedia.org/wiki/Spectre_(Sicherheitsl%C3%BCcke) gezeigt hat. Grade im Hinblick auf veraltete Browser wird es im Progressive WebApp (PWA) Aspekt sowieso sehr schwer, da die Plattform natürlich davon lebt, dass diese regelmäßig erweitert wird.

Das der Browser sicher ist, heißt aber nicht, dass unsere App sicher ist. Wir müssen uns natürlich immernoch um Dinge, wie Resource Policies, Cross Site Scripting etc. kümmern.

Wie groß werden dann solche Apps? moderne Webseiten haben schon eine absurde Größe. wenn nun noch irgendwelche runtimes angezogen werden….

Wir müssen natürlich hier erstmal unterscheiden, was “moderne Webseiten” sind. Ich interpretiere moderne Webseiten hier erstmal als “moderne Webapplikationen”, die clientseitig gerendert werden – sogenannte Single Page Applications (SPA). Es ist natürlich so, dass SPAs mit der Zeit immer mehr an Code-Größe zunehmen – und das kriegt auch der Nutzer in Form von Dateigrößen zum Downloaden zu spüren. Nach oben hin ist da keine Grenze gesetzt.

Das sind aber natürlich Probleme, für die es neben den klassischen geschenkten technischen Lösungen wie “gzipping” und “minification” bereits Lösungen gibt. Als Stichwort is hier zum Beispiel Code Splitting genannt. Beim Code Splitting kann man eben auch auf “fachliche” Modulebene, sprich z.B. Route, Bereich, Rolle o.Ä. ein Splitting vornehmen, sodass auch nur gewisse Codestücke geladen – und auch wieder verworfen werden, wenn sie nichtmehr gebraucht werden. Das führt eben dazu, dass man geladenen Code auf ein Minimum reduzieren kann.

Man muss hier aber sagen, dass das eventuell gar nicht so relevant ist. Wenn wir SPAs haben, dann sind diese in der Regel sehr gut cacheable. Wir laden dann also jeden “chunk” im besten Fall sowieso nur einmal runter. Vor allem im Hinblick auf den nächsten Step der Evolution – der Progressive WebApp (PWA).

Gehen wir den Schritt weiter zur PWA, also SPAs, die die BrowserAPIs stark in Anspruch nehmen um Werte zu generieren (Nutzung von IndexedDB, Nutzung von WebRTC etc.) und offline Fähigkeiten mitbringen, dann ist der Vorteil, dass dieselben Dinge gelten wie für SPAs (Code Splitting). Das ist ja das schöne – die APIs werden vom Browser festgelegt und müssen eben nicht implementiert, sondern bedient werden. Der Code wird ja von unserer Plattform, dem Browser, bereitgestellt. Sprich: Es hat keine Auswirkungen auf unser letztlich code-bundle.

Zu guterletzt natürlich WebAssembly binaries. Hier tut sich natürlich viel. Ich selbst kann von binaries für simples parsing von um die 20MB berichten –  das is schon sehr viel. Aber: Auch hier gilt, dass man das eben durch den Browser oder eben Service Workern gut cachen kann. Die vorgestellte AutoCAD Applikation (https://github.com/WebAssembly/design/issues/1166 )ist um die 29MB groß.

Zukunftssichere Architekturen mit Microservices

Mit dem Begriff „Microservice-Architektur“ wird der Architekturstil beschrieben, bei dem mehrere unabhängige Services eine Applikation bilden. Aber in welchen Situationen ist die Wahl dieses Ansatzes sinnvoll? Welche Konsequenzen hat es, wenn ich mich dafür entscheide? Wie finde ich den richtigen Service-Schnitt? Und wie baue ich ein passendes Frontend dazu?Der Vortrag gab einen guten Überblick über die Herausforderungen und deren Lösungsmöglichkeiten und beleuchtete dabei auch Themen wie Testing und Continuous Delivery.

Slides zum Vortrag Zukunftssichere Architekturen mit Microservices
Slides zum Vortrag Zukunftssichere Architekturen mit Microservices

Q&A zu diesem Vortrag

Zu Consumer Driven Contracts: Wie geht das am einfachsten mit einem Android/iOS Client? Wie fällt aus der App ein Testframework heraus?

Das Vorgehen bei einem Android-Client ist ähnlich wie bei einem Java-Client: Beim Tool Pact wird z.B. ein Mock-Server gestartet, dessen Verhalten im Unit-Test des Clients definiert werden kann. Dieser schreibt dann die tatsächliche Interaktion des Clients mit dem Mock-Server mit und erzeugt dadurch einen Contract, der die Interaktion widerspiegelt. Dieser kann dann über eine zentrale Stelle (z.B. einem Pact-Broker) dem Client zur Verfügung gestellt werden.

Gibt es gute pattern in einer Microservices Architektur für stark übergreifende Vorfälle, z.B. Datenlöschungswunsch eines Nutzers auf Basis einer DSGVO Anfrage?

Übergreifende Fälle wie ein Datenlöschungswunsch auf Basis einer DSGVO-Anfrage wird über Domain-Events gelöst. Dazu muss sich jeder Service bei der Messaging-Infrastruktur registrieren und auf dieses Event lauschen.

Cloud, das „New Normal“?

„Cloud is the new normal”, so Andrew R. Jassy (CIO AWS). Was also liegt näher, als genau jetzt den Schritt in die Cloud zu wagen? Denn schließlich wollen wir ja alle irgendwie ein klein wenig „normal“ sein.

Aber ist dieser Schritt wirklich so einfach, wie uns die verschiedenen Cloudanbieter glauben machen? Lässt sich eine klassische Enterprise-Architektur einfach so in die Cloud überführen oder bedarf es neuer, cloudspezifischer Architekturmuster?  Was unterscheidet dabei die verschiedenen As-a-Service-Varianten (IaaS, PaaS, BaaS und FaaS) voneinander und für welchen Anwendungsfall nimmt man was? Fragen über Fragen – aber keine Panik, der Talk lieferte Antworten.

Slides zum Vortrag Cloud Computing – Das „New Normal“?
Slides zum Vortrag Cloud Computing – Das „New Normal“?

Q&A zu diesem Vortrag

Bezüglich Cloud Maturity Model: was ist da eure Erfahrung, würdet ihr sagen es ist besser alle Stufen der Reihe nach zu durchlaufen, oder können bestimmte größere Transformatinsschritte (z.B. gleich von Ready -> Resilient oder ähnlich) gelingen? Was sind da eure Erfahrungen bisher?

Das Cloud Maturity Model ist weniger als Schritt-für-Schritt-Anleitung zu verstehen. Es dient vielmehr als eine Art Gradmesser oder Lackmustest der eigenen „Cloudability“. D.h. mit Hilfe des Cloud Maturity Models lässt sich für Unternehmen oder einzelne Projekte sehr gut abschätzen, wo man aktuell auf dem Weg hin zu Cloud native steht und welche Schritte / Aufgaben man ggf. noch vor sich hat. Auf Basis dieser Bestandsaufnahme lässt sich nun das weitere Vorgehen entscheiden.

Im weiteren Vorgehen gilt es dabei zwischen dem Nutzen von Innovation bzw. Cloud-native-Reifegrad auf der einen Seite und dem adäquaten Aufbau von Cloud-Expertise auf der anderen Seite abzuwägen. Denn ohne hinreichende Expertise wird man auf jeden Fall scheitern.

Unsere Erfahrungen in den realen Cloud-Projekten der letzten Jahre haben gezeigt, dass der Aufbau von Erfahrungen im Rahmen von PoCs, MVPs oder losgelösten Projekten und die anschließende Übertragung dieser Erfahrungen in eine allgemein gültige Cloud-Strategie und Cloud-Governance (siehe auch nächste Dragee) die schnellsten und nachhaltigsten Erfolge mit sich bringt.

Unter dem Begriff „Erfahrung“ sind dabei sowohl die Cloud-Plattform selbst, sowie das benötigtes Tooling gemeint (Technologie), als auch Fragen der Architektur und Organisation. Aber auch ganz triviale Fragestellung, wie z.B. das Entwickeln eines besseren Verständnisses für die Cloud-Kostenstrukturen des bzw. der gewählten Provider, spielen hier mit ein.

Sollte, aus welchen Gründen auch immer, zwingend eine Migration einer größeren Anwendung en-block in die Cloud notwendig sein, ist auf jeden Fall eine Schritt-für-Schritt Migration ratsam. Dabei sollte man sich aber nicht ausschließlich an den vorgegebenen Schritten des Cloud Maturity Model orientieren, sondern viel mehr schauen, wie die im Modell vorgegebenen Schritte evtl. sinnvoll – im eigenen Kontext – noch einmal weiter herunter gebrochen werden können. D.h., man würde zum Beispiel versuchen neben den ersten Teilschritten im Bereich Cloud-friendly (z.B. Skalierung und HA via Cloud, Automatisierung) parallel auch schon einmal die ersten essentiellen Schritte im Bereich Cloud-resilient (z.B. das Sammeln und Verarbeiten von Health Probe und Metriken) anzugehen.

Welche Schritte man wann genau geht, hängt stark von dem eigenen Kontext und der in der Cloud zu platzierenden Anwendung(en) bzw. Workloads ab. Hier hilft es, sich initial einen Blick zu verschaffen und eine entsprechend Cloud-Migration-Roadmap aufzusetzen, an der man sich dann im weiteren Verlauf orientieren kann. Natürlich gilt es diese Roadmap agil und iterativ, auf Basis der während der Migration gewonnenen zusätzlichen Erkenntnisse, permanent zu adaptieren.

Cloud-Transformationen sind ja recht komplex in mehreren Dimensionen (Technik, Org, Mindset, …). Würdest du da sowas wie ein „Cloud Center of Excellence“ empfehlen, oder mit welchen Begleitmaßnahmen würdest du das angehen?

Wenn nicht nur eine einzelne Anwendung sondern große Teile der Unternehmens-IT in die Cloud gehoben werden sollen, würde ich auf jeden Fall ein „Cloud Center of Excellence“ und den damit einhergehenden iterativen Aufbau einer, sich an der Cloud-Strategie orientierenden Cloud-Governance sehen.

Wichtig ist allerdings, dass sich dieses Vorgehen nicht in einem Elfenbeinturm abspielt, sondern dass das „Cloud Center of Excellence“ die Erfahrungen aus den realen Projekten aufgreift (siehe oben), bewertet und daraus verallgemeinerte Rückschlüsse für die zu entwickelnde Cloud-Governance zieht. Getreu dem Motto „aus der Praxis für die Praxis“ kommen diese dann in weiteren zukünftigen Cloud-Projekten zum Einsatz und werden dort weiter erprobt.

Aus unserer Erfahrung heraus hilft es, wenn das „Cloud Center of Excellence“ aus mindestens einem für dieses Thema dediziert bereitgestellten Mitarbeiter sowie einer Reihe von Cloud-affinen Kollegen aus den verschiedenen aktiven (Cloud-)Projekten besteht. Der dedizierte Mitarbeiter stellt sicher, dass das Thema „Cloud Excellence“ nicht im Alltagstrubel der verschiedenen Projekte untergeht – ausreichend Management Awareness vorausgesetzt!

Die Cloud-affinen Kollegen aus den verschiedenen aktiven Cloud-Projekten wiederum stellen sicher, dass die eigenen Erfahrungen und der eigene Unternehmenskontext hinreichend bei der Entwicklung der Cloud Excellence berücksichtigt wird.

Natürlich muss man hier nicht alle Erfahrungen selber machen. Mittlerweile gibt es hinreichend viele große Cloud-Projekte und Experten am Markt, die recht offen mit ihren Erfahrungen umgehen und von denen man entsprechend partizipieren kann. Trotzdem gilt es aber, auch diese Erfahrungen in den eigenen Kontext zu setzen, bevor man sie in die eigene Cloud-Governance und Cloud-Strategie einfließen lässt.

Es gibt teils Horrorstories, bei denen Bedienungsfehler effektiv ein ganzes Unternehmen gelöscht haben. Sind das Lagerfeuergeschichten und die Dienste sind inzwischen so leicht absicherbar oder ist das eine reelle Gefahr, für die man Backups außerhalb der cloud halten sollte?

Derartige Meldungen hört bzw. liesst man tatsächlich immer wieder. In der Regel stammen diese allerdings aus den Anfängen der Cloud-Historie und sind somit schon ein paar Jahre alt. Mittlerweile bieten alle Cloud-Provider hinreichend gute Sicherheitsmechanismen sowohl für Daten & Dienste, welche in der Cloud platziert werden an, als auch für die potentiell generierten Kosten an.

Allerdings greifen diese natürlich nur, wenn man sich auch an das , häufig sehr, sehr komplexe Rollen- und Rechtssystem der Cloud-Provider hält. Und genau hier liegt das Problem. Mangels eindeutiger Cloud-Strategie und Cloud-Governance erhalten einzelne Entwickler nicht selten umfangreiche Rechte auf den Cloud-Systemen, welche deutlich über das Hinausgeht, was man ihnen im eigenen Rechenzentrum zugestehen würde.

Häufig beginnt die Transition in die Cloud damit, dass ein Entwickler oder eine sehr kleine Gruppe von Entwicklern ein Unternehmens-Cloud-Account anlegt und sich selbst dann für dieses „All-In“ Rechte gibt. Dieses Vorgehen scheint in diesem Moment auch nicht weiter schlimm, da man in der Regel mit sehr kleinen MVPs in der Cloud startet. Nur leider wächst dann irgendwann der Projekt- oder Unternehmensdruck. Neuer Anforderungen werden an die Entwickler herangetragen. Weitere Projekte möchten in die Cloud und weitere Entwickler müssen entsprechend Zugänge freigeschaltet bekommen usw.

Es ist daher zwingend notwendig sich von Anfang ausgiebig mit dem Rollen- und Rechtssystem des genutzten Cloud-Providers auseinanderzusetzen und die Rechte immer nach dem Prinzip „so wenig wie möglich, so viel wie notwendig“ zu vergeben. Das gilt übrigens sowohl für die eigenen Mitarbeiter, die sich in der Cloud bewegen, als auch für die Software, sie in der Cloud lebt bzw. auf Cloud-Komponenten zugreift!

Auch bitte es sich an, den Entwicklern einen eigenen monetär und aus Sicht der zu verwendenden Ressourcen eingeschränkten Account und somit einen eigenen Playground bereitzustellen. Dies ermöglicht ihnen beliebige „Experimente“ durchzuführen ohne dabei das Unternehmens-Account weiter öffnen und somit fragiler machen zu müssen.

Multi-Cloud Stacks wie Google Anthos einsetzen oder doch lieber bei CNCF bleiben? Welchen Einfluss hat dies auf die Architektur?

Bereits bei den ersten Gehversuchen in der Cloud stellt sich die Frage, wie stark man sich auf die propritären Plattformkomponenten des einzelnen Cloud-Provider einlassen und somit ein Verdor Lock-in in Kauf nehmen soll. Diese Fragestellung gilt natürlich dann umso mehr, wenn der eigene Plan eine Multi-Cloud-Strategie vorsieht.

Eine mögliche Lösung bietet die Orientierung an den Vorschlägen der Cloud Native Computing Foundation (https://www.cncf.io) zum Aufsetzen von nachhaltigen Ökosystemen für Cloud-native Anwendungen.

Soweit, so gut. Leider bringt der vorgeschlagene Stack eine nicht unerhebliche Komplexität in der Betreuung mit sich, so dass entsprechend Mitarbeiter zunächst hinreichend gut ausgebildet werden müssen, um sie dann im Anschluss mit der permanenten Beobachtung und Verbesserung des Systems zu betreuen.

Angefangen vom Aufsetzen eine Kubernetes-Clusters, über die permanente Aktualisierung des darüber hinaus verwendeten Toolings, bis hin zur Überwachung der in dem Ökosystem laufenden Anwendungskomponenten stehen mehr als genug Aufgaben an, um den Tag gleich mehrerer Mitarbeiter zu füllen.

Nicht immer ist es möglich und/oder sinnvoll dies Arbeit wirklich im Detail selber zu vollziehen. Stattdessen bietet sich die Verwendung von entsprechenden Distributionen oder Management-Tools ab, die zum einen viele der anstehenden Aufgaben durch entsprechende Automatismen im Hintergrund erledigen bzw. durch Convenient-Schnittstellen verdichten und zum anderen eine einheitliche und deutlich besser zu handhabende Sicht auf den Zoo von Komponenten und Tools liefern. In den von uns in den letzten Jahren begleiteten Cloud-Projekten sind wir, bis auf in ganz wenigen Ausnahmen, grundsätzlich diesen weg gegangen.

Wie vorab schon bei den Cloud-Providern, stellt sich allerdings auch bei diesen Tools die Frage, wie stark man sich auf die individuellen Features der Distributionen bzw. Management Plattformen einlassen und sich somit abhängig von diesen machen möchte. Zumal man ja bewusst auf Kubernetes und Co gesetzt hat, um genau dem Dilemma der Abhängigkeit (zu einem Cloud-Provider) zu entgehen!

Aus unserer Erfahrung heraus hat sich ein hybrider Ansatz als gut erwiesen, bei dem zwar auf entsprechende Distributionen bzw. Management Plattformen zurückgegriffen wird, bei deren Verwendung aber sorgsam darauf geachtet wird, an welchen Stellen man sich von Standards bzw. de-facto Standards entfernt. Immer dann, wenn man diesen Schritt geht, sollte dies auch eine bewusste Entscheidung sein.

So lässt sich z.B. der Aufbau eines Kubernetes Clusters mit Kubernetes Bordmitteln beschreiben (also im Standard) oder aber via proprietärer und in der Regel entsprechend einfacherer Mittel. Trotzdem würden wir in diesem Fall auf die Verwendung des (de facto) Standards setzen, um dieses Herzstück unserer Cloud-Infrastruktur relativ einfach portieren zu können. Gleiches gilt z.B. für die Wahl der Monitoring-Werkzeuge, wie dem Metrik- oder das Tracing-Format (openMetrics, openTracing).

Mit Hilfe dieser kleinen Regeln lässt sich bereits ein Großteil der Vorteile der Distributionen und Management Plattformen nutzen ohne dabei eine zu starke Abhängigkeit einzugehen und sich somit zwingend an das gewählte Tooling zu binden.


Wie sind andere Kunden aus den Branchen Versicherungen/Banken in den Bereichen Web bzw. Cloud Technologien aufgestellt?

Wir, als branchenneutraler Lösungsanbieter, sehen den Trend hin zu „zeitgemäßer“ Software über all unsere Kunden und somit alle Branchen hinweg. Insbesondere Kunden mit dedizierten Kundenportalen (B2C), wie z.B. Textilhersteller, Banken oder Versicherungen aber auch Anbieter anderer Produkte (B2C & B2B), wie z.B. Logistik- oder Energie-Unternehmen, setzen bei ihren Lösungen mit immer stärker wachsender Priorität auf neue Web Technologien in Kombination mit modularen Backend Services (Software-as-a-Service) und der Cloud.

Ob man im Frontend am Ende tatsächlich alle Buzzwords, wie Single Page Applications, Progressive Web Apps, Offline-first und Web Components im Detail befriedigt oder den Anwendern einfach „nur“ eine in ihrem Kontext ergonomisch wirklich gut funktionierende Web Anwendung zur Verfügung stellt, ist dabei egal.

Das Backend muss natürlich auch nicht zwingend auf Microservices basieren. Es sollte aber zumindest so aufgebaut sein, dass neben zentralen Komponenten (z.B. in Form einer Plattform), einzelne Module, die unabhängig voneinander entwickelt und getestet werden können, die verschiednen fachlichen Bausteine der Software abbilden.

Und auch der Schritt in Richtung Cloud bedeutet nicht zwangsläufig, dass man sich auf einen der großen Player, wie AWS, Microsoft oder Google, einlassen muss. Wichtig ist vielmehr, dass man sich dem Paradigma der schnellen Provisionierung und elastischen Infrastruktur verschreibt. Egal ob in der Private oder Public Cloud.

Unsere Kunden haben verstanden, dass sie nur mittels moderner Softwaresysteme – und natürlich einer entsprechenden agilen Organisation – in der Lage sind, auf die schnelllebigen Anforderungen am Markt zu reagieren. Es geht also nicht (nur) um schicke Oberflächen und tolle Technologien sondern vor allem um Investitionen in Wettbewerbsfähigkeit und Zukunft.


Zur OPEN THANX 2021.

No items found.

Weitere Artikel aus unserem Blog