YAML ↔ JSON an toàn | K8s/CI config vs API — tránh thụt lề & secret

(Cập nhật: 19 tháng 7, 2026 ) YAML JSON Kubernetes CI GitHub Actions DevOps
Kết luận

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 trapduplicate 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

YAML vs JSON trong công việc hàng ngày
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 workflow sang 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.10 có thể thành float 1.1 tùy loader — quote "1.10" khi là string.
  • yes / no / on / off đôi khi thành boolean — quote nếu muốn string.
  • Multiline |> 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ướcViệc làm
1Thay giá trị thật bằng REDACTED / ***
2Convert trên YAML ↔ JSON (xử lý trình duyệt)
3Kiểm tra cây key; không commit kết quả còn secret
4Giá 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:

  1. Chọn YAML → JSON hoặc JSON → YAML
  2. Dán input → Convert
  3. Đọc lỗi parse (nếu có) → sửa nguồn
  4. 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 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.