YAML is the configuration language of modern DevOps. Kubernetes manifests, Docker Compose files, Ansible playbooks, and GitHub Actions workflows all use YAML. Understanding YAML deeply is essential for cloud-native development and infrastructure automation.
| Item | Syntax / Value | Description |
|---|---|---|
| k8s Deployment | apiVersion: apps/v1 / kind: Deployment | Kubernetes Deployment manifest |
| k8s metadata | metadata: name, namespace, labels, annotations | Kubernetes object metadata |
| k8s spec | spec: replicas, selector, template, containers | Deployment specification |
| k8s resources | resources: requests/limits: cpu/memory | Container resource constraints |
| k8s env vars | env: - name: VAR / value: val / valueFrom: | Container environment variables |
| k8s ConfigMap | kind: ConfigMap / data: key: value | Non-secret configuration data |
| k8s Secret | kind: Secret / data: key: base64val | Secret data (base64 encoded) |
| k8s Service | kind: Service / spec: ports, selector, type | Network service definition |
| k8s Ingress | kind: Ingress / spec: rules, tls | HTTP routing rules |
| k8s namespace | kubectl apply -f manifest.yaml -n namespace | Apply to specific namespace |
| Docker Compose | version / services / networks / volumes | docker-compose.yml structure |
| Compose service | image, build, ports, environment, volumes | Container service definition |
| Compose depends_on | depends_on: [db, redis] | Service startup dependency order |
| Compose healthcheck | healthcheck: test, interval, timeout, retries | Container health check |
| Ansible playbook | - name / hosts / become / tasks | Playbook structure |
| Ansible task | - name: / module: / with_items: / when: | Task definition |
| Ansible vars | vars: / vars_files: / group_vars/ | Variable definitions |
| Ansible handlers | handlers: - name: / listen: | Triggered on change notification |
| Ansible roles | roles: / defaults/ tasks/ handlers/ templates/ | Role directory structure |
| GHA workflow | on: / jobs: / steps: / uses: / run: | GitHub Actions workflow structure |
| GHA triggers | on: push/pull_request/schedule/workflow_dispatch | Event triggers |
| GHA matrix | strategy: matrix: os/python-version | Parallel build matrix |
| GHA secrets | secrets.GITHUB_TOKEN / env: MY_VAR | Access secrets and env vars |
| GHA actions | uses: actions/checkout@v4 | Use pre-built action |
# ── Kubernetes Deployment ────────────────────────────────────
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mywebuniversity-api
namespace: production
labels:
app: mywebuniversity
tier: backend
version: "2.0"
spec:
replicas: 3
selector:
matchLabels:
app: mywebuniversity
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: mywebuniversity
tier: backend
spec:
containers:
- name: api
image: mywebuniversity/api:2.0.1
ports:
- containerPort: 8080
env:
- name: NODE_ENV
value: production
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: password
- name: REDIS_URL
valueFrom:
configMapKeyRef:
name: app-config
key: redis_url
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "512Mi"
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
periodSeconds: 30
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
---
# ── Docker Compose ───────────────────────────────────────────
services:
api:
build:
context: .
dockerfile: Dockerfile
args:
NODE_VERSION: "20"
image: mywebuniversity/api:latest
ports:
- "3000:3000"
environment:
NODE_ENV: development
DB_HOST: db
REDIS_HOST: cache
volumes:
- ./src:/app/src
- /app/node_modules
depends_on:
db:
condition: service_healthy
cache:
condition: service_started
restart: unless-stopped
db:
image: postgres:16-alpine
environment:
POSTGRES_DB: mywebuniversity
POSTGRES_USER: admin
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U admin -d mywebuniversity"]
interval: 10s
timeout: 5s
retries: 5
cache:
image: redis:7-alpine
command: redis-server --maxmemory 256mb --maxmemory-policy allkeys-lru
volumes:
postgres_data:
---
# ── GitHub Actions CI/CD ─────────────────────────────────────
name: CI/CD Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
schedule:
- cron: '0 6 * * 1' # Every Monday at 6am UTC
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.10', '3.11', '3.12']
os: [ubuntu-latest, macos-latest]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
pip install -r requirements.txt
pip install pytest pytest-cov
- name: Run tests
run: pytest --cov=. --cov-report=xml
- name: Upload coverage
uses: codecov/codecov-action@v4
deploy:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: Deploy to production
env:
SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
run: |
echo "$SSH_KEY" > /tmp/deploy_key
chmod 600 /tmp/deploy_key
ssh -i /tmp/deploy_key deploy@mywebuniversity.com \
'cd /app && git pull && systemctl restart api'
---
# ── Ansible Playbook ─────────────────────────────────────────
---
- name: Configure MyWebUniversity web server
hosts: webservers
become: true
vars:
app_user: www-data
app_dir: /var/www/React/prod
node_ver: "20"
vars_files:
- vars/secrets.yml
pre_tasks:
- name: Update apt cache
apt:
update_cache: true
cache_valid_time: 3600
tasks:
- name: Install system packages
apt:
name:
- apache2
- python3
- python3-pip
- git
state: present
- name: Enable Apache CGI module
apache2_module:
name: cgid
state: present
notify: Restart Apache
- name: Deploy application files
copy:
src: "{{ item }}"
dest: "{{ app_dir }}/"
owner: "{{ app_user }}"
mode: "0644"
with_fileglob:
- files/*.html
notify: Reload Apache
- name: Deploy CGI scripts
copy:
src: cgi-bin/
dest: /usr/lib/cgi-bin/
owner: "{{ app_user }}"
mode: "0755"
handlers:
- name: Restart Apache
service:
name: apache2
state: restarted
- name: Reload Apache
service:
name: apache2
state: reloaded