付録: YAMLテクニック

このガイドのほとんどは、テンプレート言語の作成に焦点を当ててきました。ここでは、YAML形式を見ていきます。YAMLには、テンプレート作成者として、テンプレートのエラーを少なくし、読みやすくするために使用できるいくつかの便利な機能があります。

スカラーとコレクション

YAML仕様によると、2種類の集合があり、多くのスカラー型があります。

2種類の集合は、マップとシーケンスです。

map:
  one: 1
  two: 2
  three: 3

sequence:
  - one
  - two
  - three

スカラー値は、個々の値(集合とは対照的)です。

YAMLのスカラー型

Helmの方言のYAMLでは、値のスカラーデータ型は、リソース定義のKubernetesスキーマを含む複雑な一連のルールによって決定されます。しかし、型を推論する際には、次のルールが当てはまる傾向があります。

整数または浮動小数点が引用符なしのベアワードである場合、通常は数値型として扱われます。

count: 1
size: 2.34

しかし、引用符で囲まれている場合は、文字列として扱われます。

count: "1" # <-- string, not int
size: '2.34' # <-- string, not float

ブール値についても同様です。

isGood: true   # bool
answer: "true" # string

空の値を表す単語はnullnilではありません)。

port: "80"は有効なYAMLであり、テンプレートエンジンとYAMLパーサーの両方を通過しますが、Kubernetesがportを整数と期待している場合は失敗します。

場合によっては、YAMLノードタグを使用して特定の型推論を強制することができます。

coffee: "yes, please"
age: !!str 21
port: !!int "80"

上記では、!!strはパーサーにageが整数のように見える場合でも文字列であることを伝えます。そしてportは、引用符で囲まれている場合でも整数として扱われます。

YAMLの文字列

YAMLドキュメントに配置するデータの多くは文字列です。YAMLには、文字列を表す方法が複数あります。このセクションでは、その方法を説明し、いくつかの使用方法を示します。

文字列を宣言する3つの「インライン」の方法があります。

way1: bare words
way2: "double-quoted strings"
way3: 'single-quoted strings'

すべてのインラインスタイルは1行でなければなりません。

  • ベアワードは引用符で囲まれておらず、エスケープされていません。このため、使用する文字に注意する必要があります。
  • 二重引用符で囲まれた文字列では、特定の文字を\でエスケープできます。たとえば"\"Hello\", she said"。改行は\nでエスケープできます。
  • 単一引用符で囲まれた文字列は「リテラル」文字列であり、\を使用して文字をエスケープしません。唯一のエスケープシーケンスは''であり、これは単一の'としてデコードされます。

1行の文字列に加えて、複数行の文字列を宣言できます。

coffee: |
  Latte
  Cappuccino
  Espresso  

上記は、coffeeの値をLatte\nCappuccino\nEspresso\nと等価な単一の文字列として扱います。

|の後の最初の行は、正しくインデントされている必要があることに注意してください。そのため、上記の例をこのように壊すことができます。

coffee: |
                  Latte
  Cappuccino
  Espresso

Latteのインデントが正しくないため、このようなエラーが発生します。

Error parsing file: error converting YAML to JSON: yaml: line 7: did not find expected key

テンプレートでは、上記のエラーから保護するために、複数行ドキュメントに偽の「最初の行」の内容を入れる方が安全な場合があります。

coffee: |
  # Commented first line
         Latte
  Cappuccino
  Espresso  

その最初の行が何であれ、文字列の出力には保存されることに注意してください。たとえば、このテクニックを使用してファイルの内容をConfigMapに挿入する場合、コメントは、そのエントリを読み取るものの種類である必要があります。

複数行文字列でのスペースの制御

上記の例では、|を使用して複数行文字列を示しました。しかし、文字列の内容には末尾の\nが続いていたことに注意してください。YAMLプロセッサに末尾の改行を削除させたい場合は、|の後に-を追加できます。

coffee: |-
  Latte
  Cappuccino
  Espresso  

これで、coffeeの値はLatte\nCappuccino\nEspresso(末尾の\nなし)になります。

他の場合、すべての末尾の空白を保持したい場合があります。これは|+表記法を使用して行うことができます。

coffee: |+
  Latte
  Cappuccino
  Espresso  


another: value

これで、coffeeの値はLatte\nCappuccino\nEspresso\n\n\nになります。

テキストブロック内のインデントは保持され、改行も保持されます。

coffee: |-
  Latte
    12 oz
    16 oz
  Cappuccino
  Espresso  

上記の場合、coffeeLatte\n 12 oz\n 16 oz\nCappuccino\nEspressoになります。

インデントとテンプレート

テンプレートを作成する際、ファイルの内容をテンプレートに挿入したいと思うかもしれません。前の章で見たように、これを行うには2つの方法があります。

  • {{ .Files.Get "FILENAME" }}を使用して、チャート内のファイルの内容を取得します。
  • {{ include "TEMPLATE" . }}を使用してテンプレートをレンダリングし、その内容をチャートに配置します。

ファイルをYAMLに挿入する際には、上記の複数行のルールを理解しておくことが重要です。多くの場合、静的ファイルを挿入する最も簡単な方法は、次のような方法です。

myfile: |
{{ .Files.Get "myfile.txt" | indent 2 }}

上記のインデント方法に注意してください。indent 2は、テンプレートエンジンに「myfile.txt」の各行を2つのスペースでインデントするように指示します。テンプレート行をインデントしないことに注意してください。なぜなら、インデントした場合、最初の行のファイル内容は2回インデントされるからです。

折り畳まれた複数行文字列

YAMLで複数行の文字列を表したいが、解釈されたときに1つの長い行として扱われるようにしたい場合があります。これは「折り畳み」と呼ばれます。折り畳まれたブロックを宣言するには、|の代わりに>を使用します。

coffee: >
  Latte
  Cappuccino
  Espresso  

上記のcoffeeの値はLatte Cappuccino Espresso\nになります。最後の改行を除くすべての改行はスペースに変換されることに注意してください。空白制御を折り畳まれたテキストマーカーと組み合わせることができるため、>-はすべての改行を置き換えたり、トリミングしたりします。

折り畳まれた構文では、テキストのインデントにより行が保持されることに注意してください。

coffee: >-
  Latte
    12 oz
    16 oz
  Cappuccino
  Espresso  

上記はLatte\n 12 oz\n 16 oz\nCappuccino Espressoを生成します。スペースと改行の両方がまだ存在することに注意してください。

1つのファイルへの複数のドキュメントの埋め込み

複数のYAMLドキュメントを1つのファイルに配置することは可能です。これは、新しいドキュメントの前に---を付け、ドキュメントの最後に...を付けることによって行われます。


---
document:1
...
---
document: 2
...

多くの場合、---または...のいずれかは省略できます。

Helmの一部のファイルには、複数のドキュメントを含めることができません。たとえば、values.yamlファイル内に複数のドキュメントが提供されている場合、最初のドキュメントのみが使用されます。

ただし、テンプレートファイルには複数のドキュメントを含めることができます。このような場合、ファイル(とそのすべてのドキュメント)はテンプレートレンダリング中に1つのオブジェクトとして扱われます。しかし、結果のYAMLは、Kubernetesに供給される前に複数のドキュメントに分割されます。

複数のドキュメントを1つのファイルに含めるのは、どうしても必要な場合にのみ推奨します。1つのファイルに複数のドキュメントが含まれていると、デバッグが困難になる可能性があります。

YAMLはJSONのスーパーセットです

YAMLはJSONのスーパーセットであるため、有効なJSONドキュメントは原則として有効なYAMLでもあります。

{
  "coffee": "yes, please",
  "coffees": [
    "Latte", "Cappuccino", "Espresso"
  ]
}

これは、別の表現方法です。

coffee: yes, please
coffees:
- Latte
- Cappuccino
- Espresso

そして、これら2つは(注意深く)混在させることができます。

coffee: "yes, please"
coffees: [ "Latte", "Cappuccino", "Espresso"]

これら3つはすべて、同じ内部表現に解析されるはずです。

これは、`values.yaml`などのファイルにJSONデータを含めることができることを意味しますが、Helmはファイル拡張子`.json`を有効なサフィックスとして扱いません。

YAMLアンカー

YAML仕様では、値への参照を保存し、後でその参照によって値を参照する方法が提供されています。YAMLではこれを「アンカー」と呼びます。

coffee: "yes, please"
favorite: &favoriteCoffee "Cappuccino"
coffees:
  - Latte
  - *favoriteCoffee
  - Espresso

上記では、`&favoriteCoffee`が`Cappuccino`への参照を設定しています。その後、その参照が`*favoriteCoffee`として使用されます。そのため、`coffees`は`Latte, Cappuccino, Espresso`になります。

アンカーが役立つケースはいくつかありますが、微妙なバグを引き起こす可能性のある側面が1つあります。YAMLが最初に消費されると、参照は展開されて破棄されます。

したがって、上記の例をデコードして再エンコードすると、結果のYAMLは次のようになります。

coffee: yes, please
favorite: Cappuccino
coffees:
- Latte
- Cappuccino
- Espresso

HelmとKubernetesは、YAMLファイルを頻繁に読み取り、変更し、書き直すため、アンカーは失われます。