Die Konfigurationssprache YAML ("YAML Ain't Markup Language", ursprünglich "Yet Another Markup Language") bildet das Herzstück vieler moderner Anwendungen - etwa Kubernetes, Ansible, CircleCI und Salt. Dabei bietet YAML viele Vorteile, etwa Lesbarkeit, Flexibilität und die Möglichkeit, mit JSON-Dateien zu arbeiten. Allerdings hält die Markup Language für Ungeübte auch einige Fallstricke und Stolperfallen bereit.
Doch auch erfahrene YAML-Profis können von Problemen überrascht werden, wenn diese sich durch scheinbar harmloses Verhalten ankündigen. Die folgenden sieben Maßnahmen können Sie vor den lästigsten Problemen mit YAML bewahren.
1. Im Zweifel auf Strings setzen
Die wichtigste Defensivpraxis, die Sie anwenden können, wenn Sie in YAML schreiben: Zitieren Sie alles, was ein String sein soll. Eine der bekanntesten Eigenheiten von YAML ist es, dass man Strings auch ohne Quotes schreiben kann:
- movie:
title: Blade Runner
year: 1982
In diesem Beispiel werden die Keywords movie
, title
und year
als Zeichenketten interpretiert, ebenso wie der Wert Blade Runner
. Der Wert 1982
wird als Zahl geparst.
Aber was passiert hier:
- movie:
title: 1979
year: 2016
Der Filmtitel wird in diesem Fall als Zahl interpretiert. Doch es geht noch schlimmer:
- movie:
title: No
year: 2012
Die Wahrscheinlichkeit, dass dieser Titel als Boolescher Wert interpretiert wird, ist enorm hoch.
Wenn Sie absolut sichergehen wollen, dass Schlüssel und Werte als Zeichenketten interpretiert werden, und sich vor möglichen Mehrdeutigkeiten schützen wollen (und in YAML können sich viele Mehrdeutigkeiten einschleichen), dann quotieren Sie Ihre Zeichenketten:
- "movie":
"title": "Blade Runner"
"year": 1982
Wenn Sie Strings aus irgendeinem Grund nicht in Anführungszeichen setzen können, können Sie ein Präfix verwenden, um den Typ anzugeben. Das macht YAML zwar etwas unübersichtlicher, ist aber genauso eindeutig wie die Anführungszeichen:
2. Mehrzeilige Zeichenketten absichern
YAML bietet mehrere Möglichkeiten, mehrzeilige Zeichenketten darzustellen, je nachdem, wie diese formatiert sind. So können etwa Zeichenketten, die nicht in Anführungszeichen gesetzt sind, auf mehrere Zeilen aufgeteilt werden, indem ihnen ein >
vorangestellt wird:
long string: >
This is a long string
Beachten Sie, dass bei Verwendung von >
automatisch ein \n
am Ende der Zeichenkette angehängt wird. Wenn Sie diesen Zeilenumbruch vermeiden wollen, verwenden Sie >-
anstelle von >
.
Wenn Sie Zeichenketten in Anführungszeichen setzen, müssen Sie jedem Zeilenumbruch einen Backslash voranstellen:
long string: "This is a long string \
that spans multiple lines."
Beachten Sie, dass Leerzeichen nach einem Zeilenumbruch als YAML-Formatierung und nicht als Teil des Strings interpretiert werden. Aus diesem Grund wird im obigen Beispiel das Leerzeichen vor dem Backslash eingefügt. Es stellt sicher, dass die Wörter string
und that
nicht zusammenlaufen.
3. Booleans explizit angeben
Wie bereits angedeutet, ist eine weitere große Schwierigkeit von YAML, boolesche Werte anzugeben. Dafür bietet YAML so viele Möglichkeiten, dass eine beabsichtigte Zeichenkette nur allzu leicht als Boolean interpretiert werden kann.
Ein vielzitiertes Beispiel hierfür ist das Problem mit Länderkennungen. Während US
oder UK
kein Problem darstellen, ist das beispielweise im Fall von NO
anders - die Kennung wird nicht als Zeichenkette, sondern als Boolean ausgewertet.
Wenn immer möglich, sollten Sie deshalb sowohl Booleans, als auch kürzere Zeichenketten, die als solche fehlinterpretiert werden könnten, bewusst explizit angeben. Das YAML-Präfix für Booleans lautet !!bool
.
4. Oktalausformungen beachten
Ein unscheinbarer aber möglicherweise lästiger Fehler: YAML 1.1 verwendet eine andere Notation für Oktalzahlen als YAML 1.2. In YAML 1.1 sehen diese wie 0777
aus. In YAML 1.2 wird aus der gleichen Oktalzahl 0o777
- was deutlich weniger zweideutig ist.
Kubernetes verwendet YAML 1.1. Wenn Sie YAML mit anderen Anwendungen verwenden, die die Version 1.2 nutzen, sollten Sie besonders darauf achten, nicht die falsche Schreibweise für Oktalzahlen zu verwenden. Da diese heute in der Regel nur noch für Dateirechte verwendet werden, handelt es sich im Vergleich zu anderen YAML-Problemen um ein Sonderfall.
5. Executables meiden
Viele YAML-Bibliotheken, etwa PyYAML für Python, ermöglichen es, bei der Deserialisierung von YAML beliebige Befehle auszuführen. Erstaunlicherweise handelt es sich dabei nicht um einen Bug, sondern um eine Fähigkeit, für die YAML konzipiert wurde.
Im Falle von PyYAML wurde das Standardverhalten für die Deserialisierung schließlich so geändert, dass nur noch eine sichere Teilmenge von YAML unterstützt wird. Das ursprüngliche Verhalten kann manuell wiederhergestellt werden, allerdings sollten Sie es nach Möglichkeit vermeiden, diese Funktion zu nutzen und sie standardmäßig deaktivieren.
6. Inkonsistenzen vermeiden
Ein weiteres mögliches Problem kann auftreten, wenn unterschiedliche YAML-Verarbeitungsbibliotheken in verschiedenen Programmiersprachen unterschiedliche Ergebnisse liefern.
Ein Beispiel: Wenn Sie eine YAML-Datei haben, die boolesche Werte enthält, die als true
und false
dargestellt werden und diese mit einer anderen Bibliothek, die boolesche Werte als y
und n
oder on
und off
darstellt, reserialisieren, kann es zu unerwarteten Ergebnissen kommen. Selbst wenn sich funktional nichts am Code verändert, kann dieser völlig anders aussehen.
7. Auf YAML verzichten
Die allgemein beste Möglichkeit, Probleme mit YAML zu vermeiden, besteht darin, es nicht zu verwenden. Oder zumindest nicht direkt.
Wenn Sie YAML als Teil eines Konfigurationsprozesses schreiben müssen, kann es sicherer sein, den Code in JSON oder nativem Code (z.B. Python Dictionaries) zu schreiben und diesen dann in YAML zu serialisieren. So haben Sie mehr Kontrolle über die Objekttypen und können eine Sprache verwenden, mit der Sie bereits arbeiten.
Anderenfalls können Sie einen Linter wie beispielsweise yamllint verwenden, um YAML auf gängige Probleme zu überprüfen. So können Sie zum Beispiel wahrheitsgemäße Werte wie YES
oder off
zugunsten von true
und false
verbieten oder String-Quoting erzwingen. (fm)
Dieser Beitrag basiert auf einem Artikel unserer US-Schwesterpublikation Infoworld.