YAML Introduction and Basic Commands
Overview
YAML is a human-readable data-serialization language. It is commonly used for configuration files and in applications where data is being stored or transmitted.
YAML = YAML Ain't Markup Language
In the DevOps world, it is used for all sorts of things.
- Docker Compose Files
- CI/CD Pipeline Files
- Kubernetes Pod Files
Here are some examples of the primary features of YAML's syntax:
Key-value pairs
app: user-authentication
port: 9000
version: 1.7
Strings can come in three formats
item1: user-authentication
item2: 'user-authentication'
item3: "user-authentication"
Line Breaks need to be enclosed in a string like this
item: "user-authentication \n"
Comments
# This is a comment
Make sure to use comments to section apart your YAML file for readability.
Objects
microservice:
app: user-authentication
port: 9000
version: 1.7
This is an object named "Microservice" with attributes app, port, and version. Attribute relationships in YAML are defined by indentation.
Lists
microservices:
- app: user-authentication
port: 9000
version: 1.7
- app: shopping-cart
port: 9002
version: 1.9
You can also express the list separators on its own line.
microservices:
-
app: user-authentication
port: 9000
version: 1.7
-
app: shopping-cart
port: 9002
version: 1.9
Booleans
boolean-types:
-
boolean-true: true
boolean-false: false
-
boolean-true: yes
boolean-false: no
-
boolean-true: on
boolean-false: off
Advanced Lists
You can add strings as values to a list. The key is its preceding hierarchy node.
Fruit-Basket:
- Apple
- Banana
You can define lists inside other items by indenting as you would expect.
Basket:
Fruits:
- Apple
- Banana
Vegetables:
- Broccoli
- Carrots
- Lettuce
You can also express lists in an array-type form.
Basket:
Fruits: [Apple, Banana]
Vegetables: [Broccoli, Carrots, Lettuce]
Kubernetes Example
Here is an example file in Kubernetes.
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
-
name: nginx-container
image: nginx
ports:
- containerPort: 80
volumeMounts:
- name: nginx-vol
mountPath: /usr/nginx/html
-
name: sidecar-container
image: some-image
command: ["/bin/sh"]
args: ["-c", "echo Hello from the sidecar container; sleep 300"]
Multi-Line Strings
To preserve file line breaks:
multilineString: |
mitochondria is the
powerhouse
of the
cell
# The compiler will read this as
#
# multilineString: mitochondria is the
# powerhouse
# of the
# cell
To do the opposite and interpret multiple file lines as one string:
multilineString: >
mitochondria is the
powerhouse
of the
cell
# The compiler will read this as
# multilineString: mitochondria is the powerhouse of the cell
Example use case:
If you'd like to define several shell commands to execute in a row, you would do it like this
apiVersion: v1
kind: ConfigMap
metadata:
name: mosquitto-config-file
data:
mosquitto.conf: |
log_dest stdout
log_type all
log_timestamp true
listener 9001
Also, you could come into contact with something that looks like the following:
command:
- sh
- c
- |
#!/usr/bin/env bash -e
http() {
local path="${1}"
set -- -XGET -s --fail
# some more stuff here
curl -k "$@" "http://localhost:5601${path}"
}
http "/app/kibana"
Environment Variables
In YAML, you can access environment variables by using a dollar sign symbol.
$
In the following example, we use an environment variable that contains a database password.
command:
- /bin/sh
- -ec
- >-
mysql -h 127.0.0.1 -u root -p$MYSQL_ROOT_PASSWORD -e 'SELECT 1'
Placeholders
When you use a platform like Ansible, Helm, or Azure Pipelines, sometimes there are values that specific platform can provide. On compiling the YAML, it evaluates these expressions and places in the appropriate values. To specify where and what insert for those, you define it with either single or double curly braces:
{% raw %}
- {{ }}
{% endraw %}
aliVersion: v1
kind: Service
metadata:
name: {{ .Values.service.name }}
spec:
selector:
app: {{ .Values.service.app }}
ports:
-
protocol: TCP
port: {{ .Values.service.port }}
targetPort: {{ .Values.service.targetport }}
Components
If you have separate YAML that you want to separate out, you use three dashes.
apiVersion: v1
kind: ConfigMap
metadata:
name: mosquitto-config-file
data:
mosquitto.conf: |
log_dest stdout
log_type all
log_timestamp true
listener 9001
---
Grocery-List:
Fruits: [Apple, Banana]
Vegetables: [Broccoli, Carrots, Lettuce]