Kubernetes manifests and many tools bundle several objects in one file this way.
A YAML stream can contain several documents. A line containing just --- starts a new document; ... optionally marks the end of one. The first --- is optional.
kind: Service
---
kind: DeploymentEach document is independent: it has its own root node, and anchors don't carry over between documents.
Most libraries have two loading functions: one for a single document, which fails if the stream contains more, and one that returns all documents. In Python that's yaml.safe_load versus yaml.safe_load_all; in Go you call Decode repeatedly; kubectl apply -f reads them all.
--- also appears at the top of many files that have just one document, simply as a start marker. A directive such as %YAML 1.2 may precede it to declare the version, though few files use one.
Typical uses: several Kubernetes objects in one manifest, a log of records appended over time (... lets a reader know a document is complete), and front matter, where a Markdown file starts with a YAML document between --- lines.
An empty document (two --- in a row) loads as null, so filter out None values when iterating.
Example
# k8s.yaml: two Kubernetes objects in one file
apiVersion: v1
kind: Service
metadata:
name: web
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
...
# Python:
# import yaml
# docs = list(yaml.safe_load_all(open("k8s.yaml")))
# [d["kind"] for d in docs if d] -> ['Service', 'Deployment']
# yaml.safe_load(open("k8s.yaml")) -> ComposerError: expected a single documentRemember
- --- separates documents in one stream; ... ends one
- Use load_all style APIs to read every document
- Anchors don't cross document boundaries
Watch out for
- Calling a single-document loader on a multi-document manifest and getting an error.