YAML ↔ JSON an toàn | K8s/CI config vs API — tránh thụt lề & secret
K8s và CI sống bằng YAML; API sống bằng JSON — convert là cầu nối, không phải chỗ paste Secret production. Bẫy lớn nhất: thụt lề, key trùng, và tưởng anchor YAML còn nguyên sau khi sang JSON. Dùng YAML ↔ JSON trên trình duyệt để bắt lỗi cấu trúc trước khi kubectl apply hoặc merge workflow — vẫn redact token/password dù tool không upload server.
Dev và freelancer DevOps ở Việt Nam xoay giữa manifest Kubernetes, GitHub Actions / GitLab CI, và payload API mỗi tuần. Cùng một object env / resources / ports — hôm nay sửa YAML, ngày mai đồng nghiệp gửi JSON từ ticket. Convert sai một cấp indent có thể biến limits.memory thành string vô nghĩa hoặc nuốt key.
Bài này tập trung khi nào convert, bẫy cú pháp, và quy tắc an toàn với config gần secret — không phải từ điển YAML.
Bài viết này giúp bạn
- Chọn YAML hay JSON theo ngữ cảnh (K8s/CI vs API)
- Nhận diện indent trap và duplicate keys
- Hiểu mất mát khi anchor/alias → JSON
- Quy trình convert + redact trước khi paste
- Case study lỗi thật khi apply / chạy CI
YAML và JSON: cùng dữ liệu, khác việc
| Tiêu chí | YAML | JSON |
|---|---|---|
| Chỗ hay gặp | K8s, Helm values, Actions, compose | REST API, jq, nhiều JSON Schema |
| Đọc/sửa tay | Gọn, có comment (#) | Dài hơn; chuẩn không có comment |
| Rủi ro cú pháp | Indent, tab/space, duplicate key | Trailing comma, nháy đơn, BOM |
| Công cụ | kubectl, yq, CI runners | jq, hầu hết SDK HTTP |
Convert hữu ích khi:
- Copy snippet từ docs API (JSON) sang
ConfigMap/ values (YAML) - Đưa
workflowsang tool validate chỉ nhận JSON - So hai bản config bằng diff JSON đã chuẩn hóa indent
- Debug “YAML nhìn đúng mà parse ra object lệch”
Bẫy 1: Thụt lề (indentation trap)
YAML sau (sai) — memory không còn nằm dưới limits:
resources:
limits:
cpu: "500m"
memory: "512Mi" # lệch cấp — thành sibling của limits
Parser hợp lệ vẫn chạy; cluster nhận resources.memory thay vì resources.limits.memory. Pod không ra limit như bạn nghĩ — không có error đỏ lúc convert nếu bạn không đối chiếu cấu trúc.
Cách bắt: Convert YAML → JSON và đọc cây:
{
"resources": {
"limits": { "cpu": "500m" },
"memory": "512Mi"
}
}
Thấy ngay memory thoát khỏi limits. Sửa indent, convert lại, rồi mới apply.
Tab vs space: một số editor trộn — bật “render whitespace” khi sửa manifest.
Bẫy 2: Duplicate keys
env:
- name: NODE_ENV
value: production
env:
- name: LOG_LEVEL
value: debug
Tùy parser: key env sau ghi đè key trước → mất biến NODE_ENV, chỉ còn LOG_LEVEL. Merge tay từ hai PR rất hay tạo pattern này.
JSON không cho key trùng trong object theo kỳ vọng nghiêm — nhưng khi đi từ YAML “im lặng ghi đè”, bạn có thể mang sang JSON bản đã mất field mà không hay.
Checklist: Search tên key lặp trong file dài; hoặc parse rồi đếm độ dài mảng env.
Bẫy 3: Anchor / alias và kiểu YAML đặc thù
defaults: &defaults
retries: 3
timeout: 30
job_a:
<<: *defaults
name: build
job_b:
<<: *defaults
name: deploy
Sang JSON, thường thành bản expand đầy đủ — đúng dữ liệu, mất & / *. Mang JSON đó về YAML sẽ không tự khôi phục anchor.
Cũng lưu ý:
- Số phiên bản
1.10có thể thành float1.1tùy loader — quote"1.10"khi là string. yes/no/on/offđôi khi thành boolean — quote nếu muốn string.- Multiline
|và>không có tương đương đẹp trong JSON (thành một string có\n).
Quy trình convert an toàn (có secret-ish config)
Config “gần secret”: Conting K8s (base64), biến DATABASE_URL trong Actions, file .env nhét vào ConfigMap.
| Bước | Việc làm |
|---|---|
| 1 | Thay giá trị thật bằng REDACTED / *** |
| 2 | Convert trên YAML ↔ JSON (xử lý trình duyệt) |
| 3 | Kiểm tra cây key; không commit kết quả còn secret |
| 4 | Giá trị thật chỉ vào secret manager / sealed secret / env CI đã mã hóa |
Dù tool local-only, screenshot Slack/Discord vẫn rò. Redact là thói quen team, không phụ thuộc vendor.
Hướng convert:
- Chọn YAML → JSON hoặc JSON → YAML
- Dán input → Convert
- Đọc lỗi parse (nếu có) → sửa nguồn
- Copy output đã sạch
Case study 1: GitHub Actions — env lệch cấp
Freelancer thêm biến:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
env:
API_URL: https://api.example.com
env ngang hàng steps dưới build thì hợp lệ; nhưng khi copy từ JSON mẫu API:
{ "steps": [{ "env": { "API_URL": "..." } }] }
convert máy rồi paste nhầm env vào trong step hoặc ra ngoài job — workflow chạy thiếu biến, debug “secret chưa set” cả buổi.
Fix: Sau convert, so JSON tree với hierarchy jobs.*.env vs jobs.*.steps[].env trước khi push.
Case study 2: kubectl apply “thành công” nhưng sai limit
Manifest trông thẳng hàng trong editor (font proportional + wrap). Convert sang JSON lộ memory sai cấp như mục bẫy indent. Sửa xong, HPA và OOM hành vi khớp staging.
Bài học: Với file > 40 dòng, JSON tree là kính lúp cho YAML indent.
Checklist trước khi apply / merge
- Không còn secret thật trong buffer convert
- JSON/YAML parse không error
- Cây nested đúng (
limits,env,ports) - Không duplicate key quan trọng
- Số/version/boolean đã quote nếu cần string
- Hiểu rằng alias YAML sẽ bị expand
Công cụ liên quan
- YAML ↔ JSON — đổi hai chiều, chạy trên trình duyệt
- Định dạng JSON — pretty/minify và bắt lỗi dấu phẩy sau khi convert
- Định dạng .env — khi config là env file chứ không phải YAML
YAML và JSON không đối địch — chúng là hai mặt của cùng một object. Convert đúng và redact đủ thì K8s/CI ít “ma”, API ít lệch schema.