Velocity für komplexe CloudFormation-Templates

Cloudformation als Beschreibungssprache

Mit AWS CloudFormation lassen sich (fast) alle AWS Dienst in einer Konfigurationssprache beschreiben. Das ermöglicht Scripten von AWS-Infrastruktur. So sind die AWS Ressourcen gut dokumentiert. Die Templates können auch in Konfigurationssystemen abgelegt und versioniert werden, z.B. CodeCommit. CloudFormation hat also viele Vorteile. Ein Nachteil ist jedoch, dass die CloudFormation Templates schnell sehr groß werden. Was tun? Zum Glück gibt es verschiedene Ansätze, der Komplexität Herr zu werden.

Hier wollen wir einen einfachen Ansatz der anderen Art vorstellen: Die Verwendung der Template-Engine Velocity.

Velocity ist als Template Sprache sehr einfach gehalten. Die Befehle sind mit einem Hash # versehen, Objekte werden mit $ referenziert. Zur einfachen Strukturierung von großen Cloudformation-Templates können die großen Dateien in viele kleine Dateien zerlegt werden.

Diese werden dann in das Master-Template eingefügt.

    #include("datei.cf")

bewirkt ein Einfügen als Text,

    #parse("datei.cf")

bewirkt ein Einfügen als Velocity Template. Das heißt, die eingefügte Datei wird auch durch die Velocity Template Engine interpretiert. Mit parse können also auch Mehrfachverschachtelungen realisiert werden.

Velocity Template Beispiel

Als Implementierung der Template Engine nehmen wir nicht java, sondern die “leichtere” node Implementierung als npm Package velocity. Man benötigt also:

  • Eine Installation von Node.js
  • Den Node Package Manager npm, der in der Node Installation enthalten sein sollte
  • Das Packet Velocity. Dies installiert man auf der Kommandozeile mit “npm install velocity”
  • Eine große Cloudformation Template Datei. Im Beispiel nehmen wir das Beispiel “Word Press Basic Instance” von aws.

Zu Beginn haben wir eine einzige große Datei mit 365 Zeilen. Das wird schnell unübersichtlich. Das geht einfacher.  Dazu kopiere ich die Originaldatei “bigfile.template” in eine neue Datei “smallfile.template”. Ich ersetze die Zeilen 74 bis 129 durch eine einzige include Zeile

#include("mappings.vm")

Vorher: Nachher:

Den vorher kopierten Inhalt  (Zeilen 74-129)  setze ich in eine neue Datei “mappings.vm” ein. Um eine bessere Struktur zu bekommen, speichere ich die Datei in ein neues Unterverzeichnis “include”: Die Endung “vm” steht für velocity macros. So bekommt man eine Idee, wie man große Dateien durch Unterverzeichnisse strukturieren kann. Sinnvolle Unterverzeichnisse können sein:

  • Security Groups
  • Subnetze
  • Instancen
  • Routing Tabellen

Wie setze ich die Dateien jetzt wieder in eine große Datei zusammen? Ich erstelle eine Konfigurationsdatei für node-velocity und rufe die Template Engine auf:

Einfache Konfiguration von node-velocity

In der Konfigurationsdatei müssen wir der Velocity Engine erstmal nur mitteilen, dass wir noch ein Unterverzeichnis haben, in dem nach include Dateien gesucht werden soll:

module.exports = { root: [’.’,’./include’] }

In dem Array root können weitere Verzeichnisse hinzugefügt werden. Das Generieren der Gesamtdatei ist dann ein einziger Befehl auf der Kommandozeile:

velocity -t smallfile.template -c velocity-config.js -o bigfile-new.template

Die Parameter:

-t  Das zu interpretierende Template, also der Input

-c Die Konfigurationsdatei

-o Die Ausgabe: Output

Die generierte Datei ist identisch zur alten großen Datei:

Weitere Tipps

Tipps zur Verwendung der Velocity-Engine mit Cloudformation mit YAML statt json:

  • mit YAML ist Cloudformation besser lesbar
  • in YAML ist die Einrückung von Text wichtig. Um die Einrückung zu erhalten, muss man genau auf die Inhalte der #include Dateien achten. Jedes Space oder Newline Zeichen wird eingebunden.
  • daher sind eventuell Konstrukte wie “#include(‘datei1.vm’)#include(‘datei2.vm’)” sinnvoll
  • wird mit vielen Include Dateien gearbeitet, ist es sinnvoll “# — Start Dateiname” und “#— End Dateiname” zu verwenden
  • dGenerierung der Ausgabedateien kann mit gulp automatisiert werden

  Viel Spaß beim Ausprobieren, velocity bietet noch mehr Möglichkeiten!

Similar Posts You Might Enjoy

Velocity for complex CloudFormation templates

Cloudformation as a description language With AWS CloudFormation, (almost) all AWS service can be described in a configuration language. This enables scripting of AWS infrastructure. Thus, AWS resources are well documented. The templates can also be stored and versioned in configuration systems, e.g. CodeCommit. So CloudFormation has many advantages. However, one disadvantage is that CloudFormation templates quickly become very large. What to do? Fortunately, there are several approaches to deal with the complexity. - by Gernot Glawe

Clouds - einfaches Management von CloudFormation Templates

Infrastruktur als Code ist eine (Heraus)Forderung von DevOps. Die Infrastrukturbeschreibungssprache von AWS heißt CloudFormation. Hat man sich erstmal eingearbeitet, greift man immer häufiger zum Texteditor statt zur Console, um AWS Ressourcen zu erstellen. Und eh man es sich versieht, hat man eine unüberschaubare Anzahl von Cloudformation Templates. Und dann steht man vor der Aufgabe, diese zu verwalten. Hier wollen wir ein paar Möglichkeiten dafür vorstellen. - by Gernot Glawe

Einleitung zu tRick

Wer träumt nicht davon das Infrastructure as Code Framwork zu benutzen, das die eigenen Anforderungen bestens erfüllt? Aber wie findet man nun dieses eine richtige Framework für seinen Anwendungsfall, den “Alleskönner” oder den “Spezialisten”? Auch wir bei tecRacer haben immer wieder mit unterschiedlichsten Infrastructure as Code Frameworks zu tun. Bei unseren Projekten im AWS Umfeld steht uns eine große Zahl an möglichen Tools zur Verfügung. Aber worin genau besteht der Vorteil von Infrastructure as Code Frameworks gegenüber einer manuellen Bereitstellung von Infrastruktur-Resourcen? - by Marco Tesch