Docker, Kubernetes, GitHub Actions 또는 거의 모든 현대적인 DevOps 도구를 사용하고 있다면, 알든 모르든 이미 YAML을 쓰고 있는 겁니다. YAML("YAML Ain't Markup Language"의 약자 — 네, 재귀적 약어입니다)은 사람이 읽기 가장 쉬운 데이터 형식으로 설계되었습니다.
함께 하나씩 배워봅시다.
YAML이 존재하는 이유
JSON은 기계에는 좋지만, 200줄짜리 설정 파일을 JSON으로 작성해 본 적 있나요? 주석 없음, 어디서나 큰따옴표 필수, 5단계 중첩된 중괄호... 금방 고통스러워집니다. YAML은 이 문제를 해결하기 위해 만들어졌습니다. 괄호 대신 들여쓰기를 사용해서 설정이 깔끔하고 읽기 쉬워집니다.
같은 데이터를 JSON과 YAML로 비교해 보세요. 차이가 보이나요?
JSON:
YAML:
알아야 할 기본 사항
키-값 쌍은 YAML의 기본 중의 기본입니다. 콜론과 공백만 사용하면 됩니다: name: John Doe. 그게 전부입니다 — 대부분의 문자열에 따옴표가 필요 없습니다.
들여쓰기가 전부입니다. YAML은 구조를 표현하기 위해 공백을 사용합니다(탭은 절대 안 됩니다!). 표준은 레벨당 2칸 공백입니다. 이걸 틀리면 파일이 깨집니다. 진짜로 — YAML 사양은 이에 대해 엄격합니다.
중첩 데이터의 예시입니다:
목록은 대시와 공백을 사용합니다. YAML로 작성한 장보기 목록입니다:
문자열: 생각보다 까다롭습니다
YAML에서 대부분의 문자열은 따옴표가 필요 없습니다. 하지만 콜론, 해시를 포함하거나 잘못 해석될 수 있을 때는 따옴표를 사용해야 합니다. 예를 들어, country: NO는 YAML 1.1에서 country: false로 해석됩니다. NO가 불리언으로 취급되기 때문입니다. 이것이 악명 높은 "노르웨이 문제"이며, 실제 프로덕션에서 버그를 일으킨 적이 있습니다.
확신이 없으면 따옴표로 감싸세요: country: "NO"
여러 줄 문자열은 놀랍습니다
YAML이 진짜 빛나는 부분입니다. 파이프 |는 줄바꿈을 보존하고(스크립트에 최적), >는 줄바꿈을 공백으로 접습니다(긴 설명에 최적):
앵커와 별칭: DRY 설정 파일
YAML의 가장 멋진 기능 중 하나입니다. &로 한 번 정의하고, 나중에 *로 참조합니다:
production 블록은 defaults에서 retries: 3을 상속하면서 timeout을 오버라이드합니다. 이것은 GitHub Actions 워크플로와 Docker Compose 파일에서 같은 설정 블록을 반복하지 않아도 되니 매우 유용합니다.
YAML에서 가장 흔한 4가지 실수
- 공백 대신 탭 — 에디터가 기본으로 탭을 삽입할 수 있습니다. YAML 파일에는 공백을 사용하도록 설정하세요. 진짜로, 지금 당장 하세요.
- 불리언 함정 —
yes,no,on,off,true,false는 YAML 1.1에서 모두 불리언입니다. 문자열로 사용하려면 따옴표를 붙이세요. - 값 안의 콜론 —
message: Error: file not found는 YAML이 두 번째 키-값 구분자를 인식하기 때문에 오류가 됩니다. 따옴표를 사용하세요:message: "Error: file not found" - 끝부분 공백 — 줄 끝의 보이지 않는 공백이 이상한 파싱 동작을 일으킬 수 있습니다. 끝부분 공백을 표시해주는 에디터를 사용하세요.
매일 YAML을 사용하는 곳
YAML은 Docker Compose, Kubernetes 매니페스트, GitHub Actions, GitLab CI, Ansible 플레이북 등 수십 가지의 설정 언어입니다. DevOps나 클라우드 관련 작업을 한다면 YAML 능숙도는 필수입니다.
이상하게 작동하는 YAML 파일이 있나요? YAML Validator에 붙여넣어 문제를 즉시 찾으세요.
실전 YAML: Docker Compose 예시
실제 Docker Compose 파일을 살펴봅시다 — 웹 애플리케이션을 위해 실제로 작성할 법한 것입니다:
몇 가지 주목할 점이 있습니다: 환경 변수는 리스트 형식(- KEY=value)이나 매핑 형식(KEY: value)으로 작성할 수 있습니다. 둘 다 Docker Compose에서 작동하지만 — 일관성을 위해 하나의 스타일을 선택하고 유지하세요.
실전 YAML: GitHub Actions CI 파이프라인
푸시할 때마다 테스트를 실행하는 GitHub Actions 워크플로입니다:
깔끔하고 읽기 쉬우며 자명합니다. 같은 워크플로를 JSON으로 작성한다고 상상해 보세요 — 두 배로 길어지고 시각적으로 훨씬 읽기 어려울 것입니다.
YAML vs JSON vs TOML: 빠른 비교
YAML만이 설정 파일을 위한 JSON의 유일한 대안은 아닙니다. TOML도 인기 있는 선택지입니다(Rust의 Cargo.toml과 Python의 pyproject.toml에서 사용됩니다). 비교해 봅시다:
| 기능 | YAML | JSON | TOML |
| 주석 | 있음 (#) | 없음 | 있음 (#) |
| 가독성 | 우수 | 양호 | 매우 양호 |
| 중첩 구조 | 들여쓰기 | 중괄호 | 섹션/점 |
| 여러 줄 문자열 | 있음 (` | , >`) | 없음 | 있음 (""") |
| 타입 추론 | 있음 (위험할 수 있음) | 명시적 | 있음 (더 안전) |
| 후행 쉼표 | N/A | 불허 | 허용 |
| 에코시스템 | DevOps, K8s, CI/CD | Web APIs, Node.js | Rust, Python |
고급 YAML: 하나의 파일에 여러 문서
YAML은 ---로 구분하여 하나의 파일에 여러 문서를 지원합니다. 이것은 Kubernetes에서 여러 리소스를 한 번에 배포할 때 자주 사용됩니다:
--- 구분자는 YAML 파서에게 "이것은 새 문서입니다"라고 알려줍니다. 이런 파일에 kubectl apply -f를 실행하면 Kubernetes가 두 리소스를 모두 생성합니다.
YAML 보안: Billion Laughs 공격
대부분의 초보자가 모르는 것이 있습니다: 주의하지 않으면 YAML은 보안 위험이 될 수 있습니다. "Billion Laughs" 공격은 앵커와 별칭을 사용해 기하급수적인 데이터 확장을 만들어냅니다:
이 작은 파일은 메모리에서 기가바이트로 확장되어 애플리케이션을 크래시시킬 수 있습니다. 교훈은? 신뢰할 수 없는 YAML 입력은 절대로 파싱하지 마세요. Python에서는 yaml.load() 대신 yaml.safe_load() 같은 안전한 로딩 함수를 사용하고, YAML 파서에 메모리 제한을 설정하세요.
YAML과 JSON 간 변환
YAML은 JSON의 슈퍼셋이므로(네, 유효한 JSON은 유효한 YAML이기도 합니다!), 둘 사이의 변환은 간단합니다. 설정을 작성할 때는 YAML의 가독성을 활용하고 JSON이 필요한 API나 도구에는 JSON을 사용하고 싶을 때 유용합니다.
우리의 YAML to JSON Converter가 즉시 처리해 드립니다 — YAML을 붙여넣기만 하면 깨끗한 JSON 출력을 얻을 수 있습니다. 반대 방향은요? 가지고 있는 JSON은 이미 유효한 YAML입니다.
직접 해보세요
깨진 Kubernetes 매니페스트를 디버깅하든 새 CI 파이프라인을 설정하든, 이 도구들이 시간을 절약해 줄 것입니다:
- YAML Formatter — 들여쓰기를 수정하고 YAML 파일을 깔끔하고 일관되게 만드세요.
- YAML Validator — 배포를 망치기 전에 구문 오류를 잡으세요.
- YAML to JSON Converter — JSON 전용 도구와 연동해야 할 때 형식 간 변환하세요.
YAML에는 특이한 점이 있지만, 들여쓰기 기반 구문에 익숙해지면 JSON 대안과 비교해서 설정 파일이 얼마나 깔끔해지는지 실감하게 될 것입니다.