Skip to main content

YAML Cheat Sheet

A quick reference guide for YAML syntax and common DevOps configurations.

Basic Syntax

Key-Value Pairs

key: value
name: John Doe
count: 42

Strings

# Unquoted
message: Hello World

# Quoted
title: "The \"Quick\" Guide"
escaped: 'It\'s great'

# Multi-line (literal - preserves newlines)
description: |
First line
Second line
Third line

# Multi-line (folded - joins lines)
summary: >
This is a very long
sentence that spans
multiple lines

Numbers, Booleans, Null

integer: 42
float: 3.14
boolean: true
boolean_alt: false
null_value: null
null_alt: ~

Lists

# Block style
items:
- item1
- item2
- item3

# Flow style
items: [item1, item2, item3]

# Nested lists
matrix:
- [1, 2, 3]
- [4, 5, 6]

Dictionaries

# Block style
person:
name: John
age: 30
city: NYC

# Flow style
person: {name: John, age: 30, city: NYC}

Mixed Structures

users:
- name: Alice
age: 28
skills: [Python, Docker]
- name: Bob
age: 35
skills: [Go, Kubernetes]

Advanced Syntax

Anchors & Aliases

# Define anchor with &
defaults: &default_settings
timeout: 30
retries: 3

# Reuse with alias *
service1: &service1_ref
<<: *default_settings
port: 8080

service2:
<<: *service1_ref
port: 8081

Merge Keys

base: &base
name: app
version: 1.0

prod:
<<: *base
environment: production
debug: false

dev:
<<: *base
environment: development
debug: true

Kubernetes YAML Patterns

Pod Definition

apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
namespace: default
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"

Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: myapp:1.0
ports:
- containerPort: 8080
env:
- name: DB_HOST
value: "db.example.com"

Service

apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
type: LoadBalancer
selector:
app: web
ports:
- protocol: TCP
port: 80
targetPort: 8080

ConfigMap

apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
app.properties: |
server.port=8080
app.name=MyApp
database.yaml: |
host: db.local
port: 5432

Secret

apiVersion: v1
kind: Secret
metadata:
name: app-secret
type: Opaque
data:
username: dXNlcm5hbWU= # base64 encoded
password: cGFzc3dvcmQ= # base64 encoded

Ansible Playbook Patterns

Simple Task

---
- name: Provision servers
hosts: webservers
become: yes
tasks:
- name: Update packages
apt:
update_cache: yes
upgrade: dist

- name: Install packages
apt:
name: "{{ item }}"
state: present
loop:
- nginx
- curl
- git

Variables and Handlers

---
- name: Configure application
hosts: app_servers
vars:
app_version: 2.5.0
app_port: 8080
tasks:
- name: Deploy app
git:
repo: https://github.com/company/app.git
dest: /opt/app
version: "v{{ app_version }}"
notify: Restart app

- name: Configure firewall
ufw:
rule: allow
port: "{{ app_port }}"

handlers:
- name: Restart app
systemd:
name: myapp
state: restarted

Conditionals and Loops

---
- name: Conditional deployment
hosts: all
tasks:
- name: Install Node.js on Debian
apt:
name: nodejs
state: present
when: ansible_os_family == "Debian"

- name: Install Node.js on RedHat
yum:
name: nodejs
state: present
when: ansible_os_family == "RedHat"

- name: Create multiple users
user:
name: "{{ item }}"
state: present
loop:
- alice
- bob
- charlie

Roles

---
- name: Deploy with roles
hosts: webservers
roles:
- common
- nginx
- app
post_tasks:
- name: Health check
uri:
url: http://localhost:80/health
method: GET
register: health_result
failed_when: health_result.status != 200

Docker Compose Patterns

Basic Service Definition

version: '3.8'

services:
web:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html:ro
environment:
- TZ=UTC
restart: always

Multi-Service with Dependencies

version: '3.8'

services:
web:
build:
context: ./web
dockerfile: Dockerfile
ports:
- "3000:3000"
depends_on:
- api
- db
environment:
API_URL: http://api:8000

api:
build:
context: ./api
dockerfile: Dockerfile
expose:
- "8000"
depends_on:
- db
- redis
environment:
DATABASE_URL: postgresql://user:pass@db:5432/app
REDIS_URL: redis://redis:6379

db:
image: postgres:13
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: app
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user"]
interval: 10s
timeout: 5s
retries: 5

redis:
image: redis:6-alpine
expose:
- "6379"

volumes:
postgres_data:

networks:
default:
name: app-network

Build Context

services:
api:
build:
context: ./api
dockerfile: Dockerfile.prod
args:
BUILD_DATE: 2025-03-21
VCS_REF: abc123def456
image: myapp/api:1.0

GitHub Actions Workflow Patterns

Basic Workflow

name: CI/CD Pipeline

on:
push:
branches: [main, develop]
pull_request:
branches: [main]

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.10'
- run: pip install -r requirements.txt
- run: pytest tests/

Build and Push Docker Image

name: Build and Push Image

on:
push:
branches: [main]
tags: ['v*']

env:
REGISTRY: ghcr.io
IMAGE_NAME: mycompany/myapp

jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v3
- uses: docker/setup-buildx-action@v2
- uses: docker/login-action@v2
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/build-push-action@v4
with:
context: .
push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest

Matrix Strategy

jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.8', '3.9', '3.10', '3.11']
node-version: [16, 18, 20]
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- run: npm test
- run: pytest

AWS CodeBuild buildspec.yml

version: 0.2

phases:
pre_build:
commands:
- echo "Building application..."
- echo "Installing dependencies..."
- npm install
build:
commands:
- echo "Running tests..."
- npm test
- echo "Building application..."
- npm run build
post_build:
commands:
- echo "Build completed"
- aws s3 cp dist/ s3://my-bucket/build/ --recursive

artifacts:
files:
- dist/**/*
name: BuildArtifact

Common DevOps YAML Structures

Configuration Management

# Application config
app:
name: MyApp
version: 1.0.0
port: 8080
debug: false
features:
authentication: true
logging: true
database:
host: db.example.com
port: 5432
pool_size: 10
timeout: 30

Infrastructure as Code Pattern

# Terraform-like structure
infrastructure:
region: us-east-1
environment: production
vpc:
cidr: 10.0.0.0/16
subnets:
- name: public-1a
cidr: 10.0.1.0/24
az: us-east-1a
- name: private-1a
cidr: 10.0.10.0/24
az: us-east-1a
instances:
- name: web-1
type: t3.medium
subnet: public-1a
- name: app-1
type: t3.large
subnet: private-1a

Pipeline Configuration

pipeline:
stages:
- name: build
steps:
- script: ./scripts/build.sh
- timeout: 300
- name: test
steps:
- script: npm test
- timeout: 600
- name: deploy
steps:
- script: ./scripts/deploy.sh
- timeout: 900
when: branch == "main"

Quick Syntax Reference

SyntaxMeaningExample
:Key-value separatorkey: value
-List item- item
|Literal block (preserve newlines)description:|
>Folded block (fold lines)summary: >
&Anchor definitiondefaults: &anchor
*Alias reference<<: *anchor
<<Merge key<<: *defaults
#Comment# This is a comment
---Document start---
...Document end...
~Null valuevalue: ~
!!Type casting!!str 123

Tips and Tricks

Type Casting

string_number: !!str 123        # Forces string
integer_from_string: !!int "456" # Forces integer
boolean_from_string: !!bool "yes" # Forces boolean

Escape Special Characters

colon_in_string: "Release: v1.0.0"
quote_in_string: "He said \"hello\""
backslash: "Path: C:\\Users\\name"
newline_in_string: "Line 1\nLine 2"

Indentation Rules

# 2 spaces per level (recommended)
level1:
level2:
level3: value

# 4 spaces also valid
level1:
level2:
level3: value

# Tabs NOT allowed
# level1:
# →level2: WRONG - don't use tabs!

Common Mistakes

MistakeWrongCorrect
Using tabs→key: value key: value
Colon without spacekey:valuekey: value
Inconsistent indentationLines indent 2, then 3 spacesAll lines indent by same amount
Unquoted "no"enabled: noenabled: "no"
Comments in lists- item # comment-item\n# comment
Ambiguous booleansactive: trueactive: "true" (if string needed)

Validation and Linting

# Validate with yamllint
yamllint -d relaxed config.yaml

# Validate JSON against YAML
jq . config.json | yq -r . > config.yaml

# Check Kubernetes manifests
kubectl apply -f manifest.yaml --dry-run=client

# Online validators
# - http://www.yamllint.com/
# - https://www.onlineyaml.com/

Summary

YAML is essential for modern DevOps. Keep this cheat sheet handy for quick reference on syntax, Kubernetes, Ansible, Docker Compose, and GitHub Actions patterns.