Modernes DevOps ohne Infrastructure as Code (IaC) ist kaum möglich. In DevOps (Development und Operations) harmonisieren die beiden klassischen IT-Aufgaben Entwicklung der Software und Administration der Infrastruktur. In DevOps kann man beides nicht mehr voneinander trennen. Die alte klassische Vorgehen mit der klaren Trennung zwischen der IT-Administration, die Sie sich um den Kauf und den Betrieb der Infrastruktur kümmerte, und der Entwicklung, die für die Software oder Lösung (Solution) verantwortlich ist, verschmelzen.
Warum IaC?
Cloud, Microservices und NoSQL
Es gibt gute Gründe warum DevOps inzwischen zwingend notwenig ist. Drei gängige Trends durchkreuzen nun die klare Trennung zwischen Administration udn Entwicklung: Cloud, Microservices und NoSQL
-
Cloud: Umgebungen in der Cloud brauchen keinen klasssischen IT-Administartor mehr. Im full mangaged service übernimmt der Cloudanbieter die Aufgabe der Administration der Infrastruktur.
Ein einem sauberen Betrieb wird der normale Entwickler in die Lage versetzt, seine eigene Infrastruktur im SelfService zu betreiben ohne umfangreiche Administratorenkenntnisse zu benötigen. Die Nutzung von Infrastruktur (e.g. Computereinheiten, Datenbanken, Loadbalancer, Storages) kann über einfache webbasierte Userinterfaces erfolgen. Alles tiefergehende, wie den Betrieb der Hardware, erfolgt durch den Cloudanbieter.
-
Microservices: Microservices wie Docker bieten die Möglichkeiten kleine Mikroinstanzen (letzendlich kleine abgeschlossene Computereinheiten) mit Operating System (OS) und Software gemeinsam zu betreiben. Mikroinstanzen haben ein abgespecktes OS (z.B. Alpine) und das kleine Programm das darauf läuft. Häufig werden Mikroinstanzen auch einmal ausgeführt und dass weggeworfen um z.B. Installationen durchzuführen.
In einer Umgebung wie Kubernetes oder OpenShift ist man zudem in der Lage, diese auch parallelisiert zu betreiben (horizontale Skalierung), wobei hier der Anzahl an parallel laufender Instanzen kein Limit gesetzt ist. Die notwendigen zusätzlichen Komponenten wie Loadbalancer für den Parallelbetrieb oder auch Autoscaler zum Hinzufügen und Reduzieren weiterer Microservices bei höherer oder weniger Last oder zum Austausch von Komponeneten wegen eines Defekts, sind nur die wichtigsten, die solche Systeme wie OpenShift oder Kubernetes bereitstellen.
-
NoSQL: NoSQL-Datenbanken sind insbesondere dort im Einsatz wo es auf Ausfallsicherheit und Performanz ankommt. Mit NoSQL können Massendatn in Realtime verarbeitet werden.
Eine Notwendigkeit dabei ist das Aufteilen der Datenmengen in Shards, die auf einzelne Rechner verteilt werden. Zusaätzlich werden aber noch Zusatzkomponenten benötigt, die die Datenverteilung organisieren oder die Analyse über alle Daten aller Shards durchführen. Eine hochperformante und hochverfügbare NoSQL Datenbank kann auch mal gerne aus mehr als 10 Rechnern bestehen.
Neue Herausforderungen
In einer klassischen Webanwendung mit ihrer 3-Tier-Architektur mit Datenbank, Applikation und Webserver waren im Idealfall nur drei Komponenten zu verwalten: Datenbank-, Applikations- und Webserver. Der Betrieb erfolgte auf eigenen Maschinen im Keller. Mit Cloud und Microservices wurden plötzlich die Anzahl der Komponenten für den Betrieb deutlich erhöht.
- Datenbanken (evtl. gesplittet in verschiedene Shards wie bei NoSQL-Datenbanken, z.B. MongoDB) werden für Hochverfügbarkeit und eine höhere Performanz in Shards geschnitten und auf verschiedene Computereinheiten verteilt.
- Microservices mit der Möglichkeit massiver Parallelisierung und der Nutzung weiterer Komponenten, wie Loadbalancer, Autoscaler usw. erhöhen die Anzahl der Server massiv.
Ein IT-Administrator, der früher noch in der Lage war sich die einzelnen Komponenten seiner Infrastruktur halbwegs zu merken, ist min der Menge der neuen Komponenten vollkommen überfordert. Auch ein DevOps-Entwickler wäre mit dem manuellen Betrieb seiner Komponenten heillos überfodert. Ein hoher Grad an Verfügbarkeit (Availability) und Selbstheilung (Autostart bei Ausfall) ist zwingend notwendig um im Gesamtsystem nicht andauernd eine Downtime zu erzeugen. Diese Automatisierung ist ein Teil der Aufgabe von DevOps.
Das Wissen, wie alles zusammen funktioniert, kann nicht mehr bei einem alleine oder einem Team liegen. Besser wäre es, wenn dieses nachlesbar wäre, in einen Code gegossen und zentral abgelegt werden würde. Hier setzt nun Infrastructure as Code an. Sämtliche Komponenten können per Code gebaut und ausgeliefert (deployed) werden. Hier muss angemerkt werden, dass der Code nicht dafür verantwortlich ist, dass der laufende Betrieb gewährleistet wird, z.B. der Code bei Ausfall einer Komponneten durchgeführt wird, sondern, dass die Infrastrukur so aufgebaut wir, dass die richtigen Komponenten entwickelt/erzeugt werden um einen Ausfall einer anderen Komponente auszugleichen.
Hier liegt der deutliche Mehrwert in einer Cloudumgebung oder den Microservices. Wenn eine Instanz ausfällt kann eine neue einfach und in wenigen Sekunden bis Minuten erzeugt werden. Wenn eine physische Maschine im eigenen Keller ausfällt, dann können für Neubestellung, Einrichten usw. Tage, Wochen, Monate vergehen. Lertzteres Vorgehen in Code zu gießen ist unmöglich.
Was muss der Code tun?
Der Code ist grundsätzlich nur für den Aufbau der Infrastruktur verantwortlich, nicht für den Bau (Build) einer Software oder der Lösung. Im optimalen Fall kann der Code für den IaC nach dem Build-Prozess gefeuert werden, um den neuen Build in die Umgebung automatisiert zu integrieren.
Wird der Code erstmals ausgeführt, baut man damit alles neu auf, die Computereinheiten (virtuell Maschinen oder Microservices), Loadbalancer, Datenbanken, Server, Storages, Berechtigungen, Firewall usw., also alles was für den Betrieb des eigenen Systems notwenidg ist. Wird der Code wiederholt ausgeführt, vergleicht dieser den aktuellen Stand der Umgebung mit den Komponenten die erstellt werden sollen. Findet der Code Aktualisierungen wie neue Komponenten (z.B. eine neue Webserverversion) oder Anpassungen (z.B. einer Erhöhung des Speichers für Storages) aktualisert dieser die Komponenten automatisch in der Umbgebung.
IaC und Agilität
Zentralisiert abgelegt (z.B. in GIT) haben Mitarbeiter einen zentralen Zugang um sich zum einen über den aktuellen Stand der Infrastruktur und zum anderen über die Änderungen in der Infrastruktur zu informieren. Klassische agile Vorgehensweisen wie CodeReviews, Pairprogramming usw. werden plötzlich auch für den Infrastrukturaufbau möglich.
Welche Zusatzfunktionen gibt es noch?
Cloudanbieter wie AWS, Google Cloud, Azure für IaC bieten zudem eine Möglichkeit des Planens und Validierens des Codes gegen die eigenen Umgebung. Bei einem Neuaufbau wird darauf hingewiesen, wenn fehlerhafte Konfigurationen gemacht wurden, z.B. wenn bei einem Aufbau eines Datenspeichers die Angabe eines Volumen vergessen wurde.
Bei der Durchführung eines IaC-Prozesse wird in der Planung explizit dargestellt, welche Komponenten betroffen sind und welche geändert werden und welche bestehen bleiben. Diese Planung muss bestätigt werden, erst dann wird tatsächlich die Infrastruktur aktualisiert.
#Wie wird der IaCode aufgebaut? Klassische Softwareentwickler würden anmerken, dass der “Infrastruktur Code” ja gar kein richtiger Softwarecode ist. Meist ist dieser nämlich nicht in den klassischen Sprachen wie Java, PHP usw. geschrieben, sondern liegen eher in Formaten wie JSON oder YAML vor. Innerhalb des Codes sind dann die einzelnen Komponenten als eigene Blöcke abgelegt.
Hier z.B. ein Snippet zum Erstellen einer VirtualMachine in Google Cloud in YAML.
resources:
- name: myVM
type: compute.v1.instance
properties:
zone: us-central1-f
machineType: https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-f/machineTypes/f1-micro
disks:
- deviceName: boot
type: PERSISTENT
boot: true
autoDelete: true
initializeParams:
sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/family/debian-8
networkInterfaces:
- network: https://www.googleapis.com/compute/v1/projects/myproject/global/networks/default
accessConfigs:
- name: External NAT
type: ONE_TO_ONE_NAT
Zwar kann man in Cloudumgebungen auch mit klassischem Code arbeiten, indem man über deren API Komponenten bearbeitete. Aber wirklich effizient sind nur die von den Cloudanbieten (AWS, Cloud Cloud, Azure) vorgegebenen Formate. Nur hier sind die notwendigen Funktionen out-of-the-box vorhanden um Komponenten zu erstellen, zu aktualisieren, zu löschen, die Ausführung zu Planen und Durchzuführen.
Wie heißen die typischen IaC-Dienste?
Bei den typischen Cloudanbietern sind es die folgenden Services und Formate für IaC:
AWS: Cloudformation (JSON und YAML)
Azure: ARM Templates (JSON)
Google Cloud: Cloud Deployment Manager (JSON und YAML)
Und was gibt es noch?
Neben den Diensten der Cloudanbieter gibt es noch unabhängige Tools die IaC anbieten. Hier sei insbesondere auf Terraform der HashiCorp hingewiesen. Mit diesem Tool kann man IaC für verschiedene Cloudanbieter betreiben.
Hier ein Beispiel für die Erzeugung eines ElasticLoadBalancers in AWS (ELB) mit Terraform:
resource "aws_elb" "web" {
name = "terraform-elb-aws"
subnets = ["${aws_subnet.default.id}"]
security_groups = ["${aws_security_group.elb.id}"]
instances = ["${aws_instance.web.id}"]
listener {
instance_port = 80
instance_protocol = "http"
lb_port = 80
lb_protocol = "http"
}
}
Mit Deploymenttools wie Puppet oder Ansible kann man zwar auch IaC betreiben, der Funktionsumfang ist aber mehr auf das klasssiche Installieren von Software auf einer Maschine (IT-Automatisierung) als das Erzeugen von Maschinen ausgelegt. Es ist eher eine sehr sinnvolle Ergänzung als tatsächliches IaC.