Über unsMediaKontaktImpressum
Hendrik Pahl 13. November 2018

Continuous Delivery, Cloud & Agilität – das Dreamteam?

Cloud, Continuous Delivery, agile Methoden, Produktentwicklung – dies sind Stichwörter, die zurzeit in aller Munde sind. Jedes dieser Stichworte verspricht für sich einen Mehrwert, doch wie spielen diese Themen zusammen? Für Continuous Delivery ist die Cloud das Mittel zum Zweck, die Automationsplattform, die die Vollautomatisierung in greifbare Nähe rücken lässt. Agile Methoden sind die Entwicklungsmethodik für Produkte. Dieser Artikel zeigt auf, wie Continuous Delivery im Kontext von Cloud, agiler Entwicklung und Produktentwicklung als Integrator wirkt und die Interessenlagen im DevOps-Umfeld vereint.

Verschiedene Perspektiven einnehmen

In jedem Unternehmen gibt es unterschiedliche Interessenslagen und Motivationen, so auch rund um Continuous Delivery (CD). Die Kunst ist, um die unterschiedlichen Motivationen zu wissen und sie so zu vereinen, dass alle beteiligten Parteien den Mehrwert einer CD-Lösung erkennen.

Interessen der Entwicklungsteams

Die zunehmende Verbreitung von agilen Entwicklungsmethoden und die steigenden Anforderungen hinsichtlich schneller Lieferung von Software in kleineren Iterationen stellen Teams vor Herausforderungen. Die Automatisierung aller Prozesse und Schnittstellen ist für Entwicklungs-, Betriebs- oder DevOps-Teams der Schlüssel zur dauerhaften Lieferfähigkeit. Ein Team, dass mehrmals am Tag neue Features in die Produktion releasen will, wird schnell merken, dass das händisch kaum durchzuhalten ist. Continuous Delivery gibt uns die Möglichkeit, Release-Prozesse zu automatisieren – und so die Release-Frequenz konstant hoch zu halten. CD-Tools gibt es wie Sand am Meer – und der Aufbau von Pipelines kostet auch Zeit, von der Wartung und dem Betrieb von dezentralen, verteilen CD-Tools ganz abgesehen. In den Teams wächst mit der Zeit der Wunsch nach standardisierten Lösungen, die einfach zugänglich und einfach zu nutzen sind, die Teams dabei aber nicht in ihren spezifischen Anforderungen einschränken.

In der Realität erstellt jedoch jedes Team seine eigenen CD-Umgebungen, die von fraglicher Qualität sind und den Teams hohe Aufwände für die reine Tool-Pflege bescheren.

Interessen des Unternehmens

Für Unternehmen ist die Cloud hoch attraktiv – sie bietet die Perspektive, dass der eigene Rechenzentrumsbetrieb komplett entfällt. Entwickelt das Unternehmen zusätzlich zur Nutzung der Cloud noch eine DevOps-Kultur (hier: Ende-zu-Ende-Verantwortung in den Teams), verschieben sich auch Verantwortlichkeiten und Zuständigkeiten. Eigenverantwortliche Teams, die für ihren Service die volle Verantwortung bis in den Produktionsbetrieb übernehmen, sind auf der Prozessebene eine Herausforderung – man stelle sich vor, dass 300 Teams jeweils eigene Accounts in der Amazon-Cloud haben und eigenständig ihre Firewalls, Loadbalancer usw. konfigurieren. Um hier die Kontrolle über die Sicherheit zu behalten, gibt sich ein Unternehmen einheitliche Regeln – und übt so Governance über die Arbeit der Teams aus. Ein einfaches Beispiel: "Jede Festplatte in der Cloud muss verschlüsselt sein." Die Überprüfung auf Einhaltung dieser Regeln kostet Zeit, Geld und Nerven, findet sie doch in aller Regel nachgelagert statt, also nachdem die Ressourcen erzeugt wurden, welche die Regeln verletzen.

Diese Dokumente sind für Menschen lesbar, für Maschinen nicht.

Governance-Regeln sind häufig in Wikis oder losen Dokumenten gesammelt, in der Regel in verschiedenen Versionen, ggf. sogar verschiedenen Sprachen. Diese Dokumente sind für Menschen lesbar, für Maschinen nicht, zusätzlich stellt sich die Frage, ob die Richtlinien nicht nur allen Betroffenen bekannt sind – sondern auch, ob sie von allen wirklich verstanden wurden. Die automatisierte Überprüfung dieser Regeln ist technisch schon länger möglich, wird jedoch erst nachhaltig und sinnvoll möglich durch die Verknüpfung von Cloud-Computing und Continuous Delivery. Durch das Vorliegen von Infrastrukturbeschreibungen als Manifest (Infrastructure as Code) kann die Prüfung auf Compliance früher im Gesamtprozess stattfinden – die Teams können Fehler begehen und aus ihnen lernen, bevor die Infrastruktur erzeugt wurde, es entsteht weniger Risiko für das Unternehmen.

Continuous Delivery als Produkt begreifen & Interessen vereinen

Nehmen wir die Interessenlagen der Teams und des Unternehmens zusammen, fällt auf, dass der Anspruch nach Zugänglichkeit und Einfachheit dem Wunsch nach Kontrolle durch das Unternehmen diametral gegenübersteht. Dies gilt erst recht in der DevOps-Welt, in der Geschwindigkeit und Lieferfähigkeit kritisch für den Erfolg von Teams und Produkten werden. Lässt sich dieser Widerspruch auflösen, wenn wir über Continuous Delivery als Produkt nachdenken?

Ein Produkt zeichnet sich durch seine Eigenschaften und Funktionen aus, die dem Kunden einen spürbaren Mehrwert liefern. Ein durch den Kunden anerkannter Mehrwert ist die ultimative Legitimation für ein Produkt, denn wenn mir etwas einen Mehrwert verschafft, bin ich auch bereit, dafür zu zahlen – ein Produkt wird immer dann erfolgreich sein, wenn Kunden es nutzen wollen anstatt es nutzen zu müssen.

Hier kommt ein weiterer Widerspruch ins Spiel: Wir denken über ein Produkt nach, das aber rein interne Kunden haben wird. Warum sollten wir interne Produkte entwickeln? Am Beispiel Continuous Delivery wird deutlich, dass wir entweder in jedem Team das Rad neu erfinden können – oder die Entwicklung einer Lösung zentralisieren können. Ob es sich für jedes Team lohnt, ein eigenes Tool auszuwählen, zu automatisieren und zu warten, ist fraglich. Wenn alle Teams ein zentral entwickeltes Produkt nutzen, wird der Mehrwert für das Unternehmen spürbar, die Fokussierung in den Entwicklungsteams steigt und die Umsetzung der Governance-Richtlinien vereinfacht sich deutlich.

Am Beispiel CD könnte dies konkret bedeuten, dass ein Produktteam damit beauftragt wird, eine self-service-fähige Continuous-Delivery-Plattform aufzubauen. Der Mehrwert einer zentral entwickelten CD-Plattform (Continuous-Delivery-as-a-Service, CDaaS) ist die Vereinigung der Interessenlagen, die den Teams massiv Arbeit abnimmt und dem Unternehmen die Kontrollmöglichkeit erhält. Die Self-Service-Fähigkeit der Plattform versetzt die Teams in die Lage, bei geringen Betriebs- und Supportkosten eigenverantwortlich zu handeln und gibt dem Produktteam eine definierte Schnittstelle zu seinen Kunden. Die Finanzierung dieses Vorhabens ist aus Unternehmenssicht eine Investition, die erst mal Zeit und Geld kostet – die ersten positiven Effekte zeigen sich kurzfristig, vorausgesetzt, unsere Lösung löst auch real existierende Probleme. Um dies sicherzustellen empfiehlt es sich, dass wir vor dem Beginn der Entwicklung viele Gespräche mit Stakeholdern und potentiellen Kunden führen, um zu identifizieren, wo der Schuh besonders drückt.

Standards: Ja bitte, aber mit Bedacht!

Standardisierung bedeutet auch, dass alle in gewisser Weise gleich arbeiten. Im Falle einer vielfältigen, verteilten Softwareentwicklungs-Landschaft, kann eine zu starke Standardisierung Freiräume und Vorteile einzelner Teams zu stark einschränken. Aus diesem Grund ist es wichtig, sich über die einheitliche Arbeitsweise der Teams klar zu werden, bevor Technologieentscheidungen getroffen werden. Typischerweise kommen wir in diesem Kontext auf folgende Schlagwörter für die Arbeitsweise der Teams: eigenverantwortlich, selbstorganisiert, you build it, you run it, DevOps und Automatisierung.

Für Continuous Delivery ist verhältnismäßig viel spezifisches Tiefenwissen über die verwendeten Technologien nötig – am Beispiel Amazon Web Services (AWS) wären dies zumindest CloudFormation-Templates (im Weiteren: CF-Templates), die Bedienung der AWS-Konsole bzw. API und die einzelnen verwendeten Services (RDS für Datenbanken, SQS für Queueing-Services usw.). Eine Möglichkeit, den Teams die Arbeit zu erleichtern und die Fokussierung auf die eigentliche Lieferung zu erhöhen, ist deklaratives Arbeiten. Durch die Deklaration eines Zielzustandes teilt der Benutzer der Pipeline-Plattform mit, was sie tun soll – wie dies technisch funktioniert, muss der Benutzer nicht mehr verstehen. Beispiele für deklarative Manifeste sind CF-Templates in der Amazon-Cloud, Resource Manager Templates bei Azure oder Helm-Manifeste in Kubernetes.

Die Deklaration von Zielzuständen ermöglicht dem Benutzer, sich voll und ganz auf das Was zu fokussieren, ohne das Wie kennen zu müssen. Beispiel 1 verdeutlicht dies – ein CF-Template wird in der Amazon-Cloud ausgerollt, der Benutzer benötigt kein Wissen, wie der Deployment-Prozess im Detail funktioniert (am Beispiel gitlab-ci). Der Mehrwert von deklarativem Arbeiten entsteht durch die Testbarkeit der Pipeline-Manifeste sowie die Wiederverwendbarkeit von Artefakten über verschiedene Pipelines hinweg, zeigt sich für den Benutzer allerdings erst bei häufiger Nutzung.

Ein konkretes Problem stellt sich bei CF-Templates: Es ist vom Hersteller nicht vorgesehen, Templates zu parametrisieren. Diese Funktionalität kann wichtig sein, wenn wir in der Pipeline zwischen Test- und Produktionsumgebung unterscheiden wollen, aber gleichzeitig sicherstellen wollen, dass exakt der gleiche Stand des CF-Templates ausgerollt wird – als Beispiel sei hier der Datenbankname für unsere Anwendung genannt, der sich in den verschiedenen Umgebungen unterscheidet. Hier hilft uns ein Tool wie cfnsphere [1], welches die fehlende Parametrisierung nachrüstet und unsere Arbeit erheblich vereinfacht.

Alles wird Code – Wissen automatisieren

Findet sich die Beschreibung der Cloud-Infrastrukturen als Manifest wieder (YAML oder JSON seien hier als Beschreibungssprachen genannt), gewinnen wir die Möglichkeit dazu, diese Dateien vor dem Deployment auf Muster- bzw. Regelverletzungen zu untersuchen. Setzen wir die vom Unternehmen erstellten Governance-Richtlinien ebenfalls in Code um, können wir beispielsweise CF-Templates mit diesem Code überprüfen – die automatisierte Governance-Ausübung entsteht.

Listing 1 zeigt eine einfache Regel, implementiert in CFN_NAG [2], die überprüft, dass im CF-Template keine Standard-Benutzernamen für RDS-Datenbanken verwendet werden. Ähnliche Tools stehen für Kubernetes bereit [3], sind aber noch unreif für den Produktionseinsatz, da sie noch nicht alle relevanten Ressourcentypen unterstützen. In der Kubernetes-Welt ist die automatisierte Governance eher in der Plattform anzusiedeln, beispielsweise durch die Nutzung von Admission Controllers oder dem Operator Framework.

Listing 1:

require 'spec_helper'
require 'cfn-model'
require 'cfn-nag/custom_rules/RDSInstanceMasterUsernameRule'

describe RDSInstanceMasterUsernameRule, :rule do
  context 'RDS instance with NoEcho username' do
    it 'returns offending logical resource id' do
      cfn_model = CfnParser.new.parse read_test_template('json/rds_instance/rds_instance_no_echo_username.json')

      actual_logical_resource_ids = RDSInstanceMasterUsernameRule.new.audit_impl cfn_model
      expected_logical_resource_ids = %w[]

      expect(actual_logical_resource_ids).to eq expected_logical_resource_ids
    end
  end

  context 'RDS instance with literal username' do
    it 'says all is well' do
      cfn_model = CfnParser.new.parse read_test_template('json/rds_instance/rds_instance_literal_username.json')

      actual_logical_resource_ids = RDSInstanceMasterUsernameRule.new.audit_impl cfn_model
      expected_logical_resource_ids = %w[BadDb]

      expect(actual_logical_resource_ids).to eq expected_logical_resource_ids
    end
  end

  context 'RDS instance with NoEcho parameter that has default' do
    it 'says all is well' do
      cfn_model = CfnParser.new.parse read_test_template('json/rds_instance/rds_instance_no_echo_with_default_username.json')

      actual_logical_resource_ids = RDSInstanceMasterUsernameRule.new.audit_impl cfn_model
      expected_logical_resource_ids = %w[BadDb2]

      expect(actual_logical_resource_ids).to eq expected_logical_resource_ids
    end
  end
end

Grundvoraussetzung für die Implementierung von Governance-Richtlinien ist das Vorhandensein eben jener, im Idealfall in einer Fassung, die für alle im Unternehmen Gültigkeit besitzt und uns eine Möglichkeit bietet, über Änderungen am Regelwerk automatisiert informiert zu werden. Die einfachste Implementierung ist hier, das Regelwerk-Dokument als einfache Textdatei in einem Git-Repository abzulegen und bei jeder Änderung eine Mail-Benachrichtigung zu erzeugen.

Das Team welches das Continuous-Delivery-Produkt verantwortet, konvertiert in unserem Beispiel die menschenlesbaren Richtlinien in Code – es ist ebenfalls denkbar, dass die Veröffentlichung der Regeln direkt als Code stattfindet und die Verantwortung für die Codifizierung der Regeln mit der Verantwortung für die Regeln selbst zusammenfällt. So sparen wir uns Interpretations- und Übersetzungsfehler, Rückfragen und unklare Verantwortlichkeiten.

Continuous-Delivery-as-a-Service: Integrationsschicht erzeugt den Mehrwert

Nach der Entscheidung, welche Arbeitsweise wir den Teams zukünftig anbieten wollen und der Implementierung der Governance-Richtlinien in Code können wir uns an die Integration der einzelnen Elemente wagen, entsteht hier doch der eigentliche Mehrwert: durch die Vollautomatisierung des Prozesses und die nahtlose Integration der Werkzeuge in die Pipeline, bringen wir die Interessen des Unternehmens in Einklang mit den Interessen der Teams. Zunächst sollten wir uns Gedanken machen, welches CD-Tool als Grundlage zum Einsatz kommen soll – hierbei gilt es verschiedene Entscheidungskriterien zu berücksichtigen:

  • Haben wir schon CD-Tool(s) im Einsatz?
  • Welche Erfahrungen haben wir mit diesen Tools hinsichtlich Wartbarkeit und Integration gemacht und wieviel Wissen haben wir im Haus?
  • Integrations- und Beschaffungskosten,
  • Ggfs. weitere, individuelle Kriterien.

Die folgenden Beispiele sind mit Hilfe von gitlab-ci, dem CI/CD-Tool von gitlab [4], aufgebaut – eine andere Option kann auch der Microsoft Visual Studio Team Service [5] oder Travis CI [6] sein. Das Setup bzw. die Integration von CD-Tools in bestehende Landschaften wird hier nicht weiter beschrieben.

Mehrwert am Beispiel Amazon Web Services

Im folgenden Beispiel zeigen wir den Aufbau eines Continuous-Delivery-as-a-Service-Produktes für das Deployment von Ressourcen in der Amazon Cloud AWS. Der Gesamtaufbau in Abb. 2 beschrieben.

Für das Gesamtprodukt ergibt sich die Auswahl folgender Bestandteile:

  • Gitlab-ci als CD-Tool für die eigentliche Pipeline,
  • CFN_NAG als Linting-Tool für CF-Templates,
  • Cfnsphere für die Parametrisierung von CF-Templates,
  • Docker-Container als Laufzeitumgebung und
  • Awscli für die Interaktion mit der API der Amazon Cloud.

Gitlab-ci nutzt Docker-Container für die Ausführung der Pipeline-Artefakte – ein Umstand, den wir uns für die Implementierung zu Nutze machen können, in dem wir CFN_NAG, cfnspere und die AWS CLI in einem Container verpacken (im weiteren AWS-Deployment-Container genannt). Wichtig hierbei ist der Container Entry Point [7], über den wir sicherstellen, dass ein ganz bestimmtes Programm im Container gestartet wird – im Beispiel ein Shellscript-Wrapper, der cfnsphere aufruft und den weiteren Prozess steuert. Über den Entrypoint stellen wir sicher, dass immer der Wrapper ausgeführt wird, der seinerseits sicherstellt, dass die Governance-Überprüfung stattfindet, die somit forciert wird. Der Workflow im AWS-Deployment-Container ist in Abb. 3 beschrieben.

Der Wrapper im Container Entry Point sorgt ebenfalls dafür, dass wir in der Pipeline selbst deklarativ arbeiten können. Wir geben noch den Container an, der gestartet werden soll (cdaas_aws_deploy) – und die Stacks-Datei von cfnsphere, die ihrerseits die Parameter selbst enthält und das eigentliche CF-Template referenziert (vgl. Abb. 4 & 5).

Der Container als solches ist aber nur ein Teil der Lösung – es fehlt die Laufzeitumgebung, der gitlab runner. Vergleichbar mit Build Slaves in Jenkins, stellen die Runner in gitlab eine Laufzeitumgebung bereit, in der unsere Pipeline ausgeführt wird, konkret: in der unsere Container laufen. Um Deployments in die Amazon Cloud durchführen zu können, brauchen wir einen Runner pro Ziel-Account, mehrere Repositories an einem Runner oder mehrere Runner an einem Repository sind ebenfalls möglich. Unsere Container legen wir in einer Docker Registry oder kompatiblen Services wie Artifactory ab. Um sicher zu stellen, dass nur unsere Container in der Pipeline laufen können, limitieren wir den Runner auf unsere Registry/ unser Artifactory-Repository (s. Abb. 6).

Mit Container und Runner findet nun also der Interessenausgleich zwischen Unternehmen (Governance u. a.) und den Teams (Zugänglichkeit u. a) statt – wir stellen sicher, dass die Governance-Richtlinien eingehalten werden, während die Lösung für den Endbenutzer einfach und zugänglich bleibt.  

In ähnlicher Weise zur Anbindung von AWS können Anbindung für Azure, Kubernetes und andere Cloud-Provider und -Services geschaffen werden.

Ausblick: zertifizierter Raum, Continuous Integration

Widmen wir uns der Zukunft: Wir können sicherstellen, dass jedes Deployment durch die Governance-Prüfung läuft – und abgebrochen wird, wenn die Regeln verletzt wurden. Wir haben diverse Cloud-Provider angebunden – und können uns dem Themengebiet Continuous Integration (CI) widmen.

Im CI-Teil des Gesamtproduktes kommen Testautomatisierung, statische und dynamische Codeanalyse, Prüfung auf Open-Source-Lizenzen bzw. -Lizenzverletzungen und der Scan auf bekannte Security-Schwachstellen hinzu, unser Produkt wird also perspektivisch zur einheitlichen Lieferschnittstelle für die Teams, beginnend beim Software-Build in der Testumgebung. Die Interessen der Teams sind somit erfüllt.

Zur weiteren Wahrung der Unternehmensinteressen ist denkbar, die Logs der einzelnen Pipeline-Durchläufe revisionssicher abzuspeichern und somit auditierbar zu machen, ein zertifizierter Raum entsteht – wer mit Continuous-Delivery-as-a-Service Deployments in die Produktion durchführt, erhält Compliance- und Auditfähigkeit seiner Änderungen "per Default" dazu.

Continuous Delivery (und im weiteren Verlauf auch Continuous Integration) ist ein besonders kritischer Teil in der neuen Welt – und wird erst durch das Zusammenspiel mit Agilität und Cloud-Computing zum scharfen Schwert für die eigenen Entwicklungsteams. Entwickelt als internes Produkt, fokussiert auf die Bedürfnisse und Anforderungen der internen Kunden und unter Einhaltung der Governance-Richtlinien wird Continuous Delivery zum Mehrwert für die gesamte IT-Abteilung im Unternehmen.

Autor

Hendrik Pahl

Hendrik Pahl ist bei der DB Systel GmbH, dem IT-Dienstleister der Deutschen Bahn, als Product Owner beschäftigt und verantwortet Produkte rund um des Thema "Developer Expirience".
>> Weiterlesen
Das könnte Sie auch interessieren
botMessage_toctoc_comments_9210