YAML 검사기

브라우저에서 파싱되며 전송되지 않습니다. 매니페스트에는 시크릿, 레지스트리, 내부 호스트명이 자주 들어 있기 때문입니다. 중복 키와 탭 들여쓰기는 조용히 넘어가지 않고 오류로 처리하며, 여러 문서 스트림은 JSON 배열로 변환됩니다.

입력한 내용은 저장, 기록, 공유되지 않습니다.

YAML을 붙여넣어 문법을 검사하고 JSON으로 변환하세요. 방향을 바꾸면 JSON을 다시 YAML로 되돌릴 수 있습니다. 오류는 정확한 줄과 열을 알려줍니다. 모든 파싱이 브라우저에서 이루어지므로 시크릿이 담긴 매니페스트도 업로드되지 않습니다.

사용 방법

  1. YAML을 입력란에 붙여넣습니다.
  2. 아래 결과를 확인합니다. 유효하거나, 원인과 줄·열이 표시됩니다.
  3. JSON을 복사하거나 JSON → YAML로 전환해 반대 방향으로 변환합니다.

YAML이 보기보다 어려운 이유

YAML의 매력은 단순한 문서라면 문법이 거의 필요 없다는 점입니다. 그 대가로 파서가 많은 것을 추론해야 하며, YAML 문제의 대부분은 파서가 의도와 다른 것으로 추론하는 데서 생깁니다.

들여쓰기가 곧 구조이며, 반드시 공백이어야 합니다. 탭은 한 번도 허용된 적이 없어서, 탭을 넣도록 설정된 편집기에서는 아무 문제가 없어 보이는데도 오류가 납니다. 들여쓰기는 고정 폭이 아니라 상대적이므로, 네 칸 들여쓴 블록과 두 칸 들여쓴 형제 요소가 함께 있으면 스타일 불일치가 아니라 진짜 오류입니다.

게다가 같은 데이터를 여러 방식으로 쓸 수 있습니다. 블록 스타일과 플로 스타일, 따옴표가 있는 스칼라와 없는 스칼라, null을 쓰는 세 가지 방법이 있습니다. 값이 이들 사이의 틈에 빠지기 전까지는 아무 상관이 없지만, 빠지는 순간 큰 문제가 됩니다.

암묵적 타입 변환의 함정

따옴표 없는 스칼라는 모양에 따라 타입이 정해지는데, 그 모양이 사람들이 문자열로 쓰는 것과 겹칩니다.

대표적인 예가 버전 번호입니다. 따옴표 없는 1.10은 부동소수점 수이고 끝의 0이 유지되지 않으므로 1.1이 되어, 고정해 둔 의존성 버전이 모르는 사이에 다른 곳을 가리키게 됩니다. 앞에 0이 있는 값은 반대 방향으로 같은 문제를 겪습니다. YAML 1.2에서 0755는 8진수 파일 권한이 아니라 숫자 755이며, 0o755라고 써야 합니다. 전화번호, 계좌 참조 번호, ID 같은 긴 숫자열은 앞의 0을 잃고, 16자리를 넘으면 정밀도도 잃습니다.

유명한 것은 불리언입니다. YAML 1.1은 yes, no, on, off, y, n을 불리언으로 취급했고, 여기서 '노르웨이 문제'가 나왔습니다. NO(노르웨이)가 들어 있는 국가 목록이 false가 들어 있는 목록으로 바뀌는 것입니다. YAML 1.2 core는 이를 true와 false로만 좁혔고 이 도구도 그 규칙을 따르지만, Ruby의 Psych나 오래된 PyYAML처럼 여전히 1.1 파서를 쓰는 소프트웨어가 많습니다. 문자열로 의도한 값은 따옴표로 감싸는 습관이 안전합니다.

알아 둘 점이 더 있습니다. null은 null, ~, 또는 아무것도 쓰지 않는 방식으로 나타낼 수 있으므로, 값이 비어 있는 키는 빈 문자열이 아니라 null입니다. 그리고 YAML 1.1에서 22:22는 시간이 아니라 60진수 숫자로 해석됩니다.

여러 줄 문자열

블록 스칼라 지시자 두 개로 거의 모든 경우를 처리할 수 있으며, 잘못 고르는 것은 설정이 깨지는 흔한 원인입니다.

파이프(|)는 줄바꿈을 쓴 그대로 유지합니다. 셸 스크립트, 인증서, 내장된 설정 파일처럼 줄 구조에 의미가 있는 곳에 씁니다. 부등호(>)는 줄을 접습니다. 단일 줄바꿈은 공백이 되고 빈 줄은 줄바꿈이 되므로, 소스에서는 줄을 나누되 값에서는 이어지게 하고 싶은 긴 문단에 알맞습니다.

둘 다 끝의 줄바꿈을 제어하는 chomping 지시자를 붙일 수 있습니다. 아무것도 붙이지 않으면 줄바꿈 하나만 남기고, 마이너스(-)는 모두 없애며, 플러스(+)는 모두 남깁니다. 토큰, 키, 명령 인수처럼 끝의 줄바꿈이 받는 쪽을 망가뜨릴 때는 마이너스를, 공백을 정확히 보존해야 할 때는 플러스를 씁니다.

내용은 키를 기준으로 들여쓰며, 그 들여쓰기는 값에서 제거됩니다. 다른 줄보다 더 들여쓴 줄은 추가 공백을 유지하므로, 매니페스트 안에 넣은 스크립트도 자신의 구조를 지킬 수 있습니다.

앵커, 별칭, 병합 키

앵커는 &로 노드에 표시를 하고 별칭은 *로 그것을 참조하여, 문서 앞부분에서 정의한 값을 재사용하게 해 줍니다. CI 설정이나 compose 파일에서는 이를 이용해 거의 같은 작업이나 서비스 사이의 반복을 없앨 수 있으며, JSON이 아닌 YAML로 작성할 만한 몇 안 되는 진짜 이유 중 하나입니다.

<<: *base로 쓰는 병합 키는 한 걸음 더 나아가, 앵커가 붙은 매핑의 키를 현재 매핑에 합쳐 일부만 덮어쓸 수 있게 합니다. 다만 이것은 YAML 1.2 core에 속하지 않는 별도 명세입니다. 대부분의 파서가 구현하지만 구현하지 않는 파서도 있어 어디서나 안전하지는 않습니다.

JSON으로 변환하면 이 모든 것이 필연적으로 사라집니다. 별칭은 변환 전에 실제 값으로 풀리므로, 세 번 참조된 앵커는 참조 세 개가 아니라 데이터 복사본 세 개가 됩니다. JSON에는 주석이 없으니 주석도 사라집니다. 따라서 앵커를 많이 쓴 설정을 JSON으로 바꿨다가 되돌리면 의미는 같지만 훨씬 긴 문서가 되며, 가독성 면에서는 되돌릴 수 없는 길입니다.

따옴표, 언제 중요하고 어느 것을 쓸까

따옴표 없는 스칼라는 생김새로 타입이 정해지므로, 따옴표는 이것이 텍스트라고 말하는 방법입니다. 작은따옴표 안은 작은따옴표 두 개가 아포스트로피 하나를 뜻한다는 점만 빼면 전부 글자 그대로이고 이스케이프를 전혀 처리하지 않습니다. 그래서 'C:\path\to' 는 정확히 그 문자열입니다. 큰따옴표는 이스케이프를 처리하므로 \n 은 줄바꿈이 되고, 역슬래시 문자 자체를 쓰려면 두 번 겹쳐야 합니다.

대부분의 골칫거리를 피하는 규칙은 이렇습니다. 기본은 작은따옴표를 쓰고, 이스케이프 시퀀스가 필요할 때만 큰따옴표를 쓰며, 다른 타입으로 읽힐 여지가 있는 값은 전부 따옴표로 감싸는 것입니다. 버전 번호, 숫자만으로 된 값, 0으로 시작하는 값, 그리고 yes, no, on, off 같은 단어가 여기에 해당합니다.

값 안에 나타나기만 해도 따옴표를 강제하는 문자가 몇 개 있습니다. 뒤에 공백이 오는 콜론, 앞에 공백이 있는 해시 기호, 그리고 맨 앞의 &, *, !, %, @ 또는 백틱입니다. 중괄호나 대괄호로 시작하는 값은 플로 스타일의 시작으로 해석되므로, {{ .Values.name }} 같은 Jinja나 Helm 템플릿은 따옴표로 감싸지 않으면 파서가 중첩된 매핑으로 읽어 버립니다.

쿠버네티스와 CI 파일을 망가뜨리는 실수들

첫째는 리스트 항목의 들여쓰기입니다. 키 아래의 시퀀스는 들여 써도 되고 키와 맞춰도 되며 둘 다 적법하지만, 한 시퀀스 안의 항목들끼리는 서로 일치해야 합니다. 여러 사람이 손댄 파일에서 두 방식이 섞이면, 보고되는 줄 번호가 전혀 엉뚱한 곳을 가리키는 오류가 나옵니다.

둘째는 다중 문서 파일입니다. 대시 세 개가 문서를 구분하는데, 첫 문서만 읽는 도구는 구분자 뒤의 모든 내용을 조용히 무시합니다. 쿠버네티스 매니페스트에서 Deployment만 적용되고 Service는 적용되지 않는 이유가 바로 이것입니다. kubectl은 여러 문서를 처리하지만, 언어의 기본 로드 함수를 쓰는 수많은 스크립트는 그러지 못하고 load-all 계열 함수를 써야 합니다.

셋째는 빈 값입니다. 콜론 뒤에 아무것도 없는 키의 값은 null이지 빈 문자열도, 빈 맵도 아닙니다. 그래서 설정 블록을 주석 처리하면서 키만 남겨 두면, 사용하는 쪽이 객체를 기대한 자리에 null이 들어옵니다. YAML 위에 세워진 모든 템플릿 시스템에서 null과 빈 문자열은 서로 다르게 동작합니다.

스키마로 YAML 검증하기

파서는 파일이 문법적으로 유효하다는 것까지만 알려 줍니다. 내용이 말이 되는지 알려 주는 것은 스키마이고, 운영과 관련된 것이라면 그쪽이 더 쓸모 있는 검사입니다. YAML은 JSON과 같은 데이터 모델로 대응되기 때문에 JSON Schema를 그대로 적용할 수 있고, 대부분의 에디터가 쿠버네티스 매니페스트나 GitHub Actions 파일에서 자동 완성과 인라인 오류 표시를 제공하는 것도 이 방식입니다.

파이프라인에서는 전용 검증기가 범용 스키마보다 한 걸음 더 들어갑니다. kubeconform은 대상 버전의 쿠버네티스 API 스키마에 비추어 매니페스트를 검사하고, yamllint는 스타일을 강제하면서 들여쓰기와 중복 키 문제를 잡아내며, 대부분의 CI 시스템은 푸시하기 전에 자기 설정 파일을 로컬에서 검증할 수단을 제공합니다.

중복 키는 따로 짚어 둘 만합니다. 대부분의 파서는 중복 키를 받아들이고 마지막 것을 남기며 앞의 것을 조용히 버립니다. 그래서 긴 파일에서 두 번 설정한 값이 무시된 것처럼 보이는 것입니다. 린터는 이를 표시해 주지만, 언어 런타임은 대개 아무 말도 하지 않습니다.

YAML 위에 템플릿을 얹는 일이 괴로운 이유

Helm, Ansible, 그리고 대부분의 CI 시스템은 템플릿으로 YAML을 생성합니다. 다시 말해 텍스트 템플릿 언어로 공백에 민감한 형식을 만들어 내는 것입니다. 결과는 뻔합니다. 잘못된 들여쓰기로 값이 끼워 넣어지고, 여러 줄 문자열이 블록을 납작하게 만들고, 조건문이 한 줄을 지워 키만 덩그러니 남습니다.

고통을 줄여 주는 습관이 두 가지 있습니다. 적용하기 전에 렌더링해 보는 것, 즉 helm template이나 그에 준하는 드라이런을 돌려서 그 출력을 템플릿이 아니라 YAML로 읽는 것입니다. 그리고 템플릿 안에서 손으로 공백을 세는 대신, Helm의 nindent처럼 도구가 제공하는 들여쓰기 헬퍼를 쓰는 것입니다.

더 근본적인 대안은 텍스트가 아니라 데이터로부터 YAML을 만드는 것입니다. 진짜 프로그래밍 언어로 구조를 만든 다음 직렬화하면, 들여쓰기는 직렬화기가 알아서 할 일이 됩니다. CDK8s, Pulumi, 그리고 CUE나 Dhall 같은 설정 언어가 존재하는 이유가 바로 이것이고, 이 방식은 실패 유형 하나를 통째로 없애 줍니다.

비밀 값, 주석, 그리고 변환 후에 남는 것

YAML 설정 파일은 비밀 값이 저장소에 흘러들어 가는 가장 흔한 통로이며, 보통은 누군가 커밋 전에 지우려 했던 값입니다. 처음부터 들어가지 않게 하는 것은 워크플로의 문제로, 환경 변수, 시크릿 매니저, 또는 SOPS나 sealed secrets로 암호화한 파일을 쓰는 방법이 있습니다. 이미 들어간 것이 없는지 저장소를 한 번 훑어보는 일은 해 둘 가치가 있으며, 한 번 커밋된 것은 히스토리에 계속 남는다는 점도 기억해야 합니다.

지켜야 할 또 하나는 주석입니다. 많은 설정 파일에서 주석은 유일한 문서인데, JSON으로 변환하거나 파일을 읽어 다시 직렬화하는 프로그램을 한 번 거치면 살아남지 못합니다. 주석을 보존하면서 YAML을 제자리에서 편집하는 도구가 있습니다. 파이썬의 ruamel.yaml, 명령줄 편집용 yq가 그것이고, 사람이 유지보수하는 파일을 스크립트로 고칠 때는 이런 도구가 올바른 선택입니다.

앵커도 마찬가지입니다. JSON으로 변환하면 모든 별칭이 사본으로 펼쳐지므로, 공유 블록을 중심으로 구성한 설정은 훨씬 길어진 채로, 유지보수를 쉽게 해 주던 구조를 잃고 돌아옵니다. 기계에게는 같은 뜻이지만, 다음에 그 파일을 편집할 사람에게는 훨씬 덜한 의미가 됩니다.

자주 묻는 질문

쿠버네티스 매니페스트를 여기에 붙여넣어도 안전한가요?
안전합니다. 파서는 브라우저에서 실행되고 문서는 어디로도 전송되지 않습니다. 서버에서 처리하는 도구를 안내하지 않고 이 도구를 만든 이유가 바로 그것입니다. 매니페스트에는 이미지 레지스트리, 내부 호스트명, base64 시크릿이 흔히 들어 있는데, 그 어느 것도 기기를 벗어나지 않습니다. 이 사이트로도, AI 어시스턴트로도 가지 않습니다.
버전 번호가 왜 1.10에서 1.1로 바뀌었나요?
따옴표 없는 1.10은 실수이고, 실수에는 끝자리 0이 없기 때문입니다. 현업에서 가장 흔한 YAML 함정이며 이 도구는 그것을 감추지 않습니다. 문자열로 유지하려면 "1.10"처럼 따옴표를 쓰세요. 빌드 번호, 전화번호, 앞자리가 0인 식별자처럼 숫자로 보이지만 숫자가 아닌 값 모두에 해당합니다.
NO가 false로 바뀌는 노르웨이 문제는 여전한가요?
아닙니다. 그것은 YAML 1.1의 동작으로, NO·yes·on·off가 모두 불리언이었습니다. 이 도구는 YAML 1.2 core를 따르므로 그대로 문자열로 남습니다. 앞자리 0도 달라져서 0755는 8진수가 아니라 10진수 755입니다. 파일 모드를 뜻했다면 0o755로 쓰세요.
여러 문서가 든 파일은 어떻게 되나요?
---로 구분된 스트림은 문서마다 하나의 요소를 갖는 JSON 배열로 변환됩니다. 여러 루트 문서를 JSON으로 나타내는 정직한 방법은 이것뿐입니다. 뒤에 내용이 없는 마지막 ---는 null 항목이 되지 않고 무시됩니다. 거의 모든 매니페스트 생성기가 하나씩 붙이기 때문입니다.
편집기는 넘어가는데 왜 여기서는 중복 키를 거부하나요?
그것을 받아들이는 도구는 검사하고 있는 것이 아니기 때문입니다. YAML은 매핑 키 중복을 금지하지만 많은 파서가 조용히 마지막 값만 남겨서, 앞의 값이 경고 없이 사라집니다. 바로 그 버그를 찾으러 여기 오신 것이죠. 탭 들여쓰기를 거부하는 이유도 같습니다. YAML은 탭을 한 번도 허용한 적이 없습니다.
JSON으로 변환하면 잃는 것이 있나요?
주석과 앵커는 반드시 사라집니다. JSON에는 둘 다 없기 때문입니다. 앵커와 별칭은 변환 전에 실제 값으로 해석되므로 &base와 *base는 같은 데이터의 사본 두 개가 됩니다. 반대 방향에서는 반복되는 값을 별칭 대신 그대로 다시 쓰고, 긴 문자열을 여러 줄로 접지 않습니다.

마지막 업데이트:

문제 신고

진행 단계, 예상 결과, 실제 결과를 적어 주세요. 비밀 정보와 개인 정보는 삭제해 주세요.

관련 도구