YAML이 너무 많다
(noyaml.com)- DevOps와 CI 설정에서 YAML이 표준처럼 쓰이지만, 암묵적 타입 변환과 파서 차이 때문에 같은 설정도 예상과 다르게 해석될 수 있음
- YAML 1.1에서는
NO,07,08,04:30,0666같은 값이 불리언·숫자·시간·8진수로 바뀔 수 있어 문자열 의도를 명확히 해야 함 - GitHub Actions, Kubernetes, CloudFormation, 여러 CI 서비스 사례는 YAML 문법과 서비스별 구조가 반복 커밋, 이스케이프 중첩, 제각각인 job 표현으로 이어질 수 있음을 보여줌
- 참고 링크들은 실행 가능한 YAML, 파서별 동작 차이, 다중 행 문자열 표기, 버전
1.70이1.7로 파싱되는 문제, StrictYAML의 설계 근거를 함께 묶음 - Nickel, Dhall, CUE, Jsonnet 같은 대안도 제시되지만, 페이지 자체가 거대한 편집 가능한 텍스트 필드처럼 보여 YAML의 사용성 풍자를 그대로 이어감
DevOps 설정 언어로서의 YAML 풍자
- YAML은 DevOps 설정에서 흔히 쓰이지만, 이 페이지는 “아무도 YAML을 쓰고 싶어 하지 않는다”는 식의 문장으로 YAML 피로감을 드러냄
- YAML을 DevOps 기술로 쓰는 이유를 역설적으로 나열함
- 항상 컴파일되고 배포 가능하다는 식으로 풍자함
- 개발 중 강제 오류 처리가 없고, 프로덕션 런타임에서 문제가 터진다는 점을 비꼼
- 줄 번호가 있는 스택 트레이스보다 “무언가 깨졌다”는 메시지가 낫다는 식으로 말함
- 새 CI 파이프라인을 만들 때 시간을 태워야 한다는 불만을 담음
- Kubernetes가 쓴다는 이유로 안전한 선택처럼 취급되는 상황을 풍자함
- JSON과 달리 주석을 지원한다는 장점도 함께 언급함
암묵적 타입 변환이 만드는 함정
- YAML 1.1에서는
NO가 불리언 타입으로 파싱될 수 있음NO: Norway는 국가 코드가 아니라 불리언 해석 문제를 일으킬 수 있음- 문자열을 의도했다면
"NO"처럼 따옴표로 감싸야 함 - YAML 1.1 명세에는
true또는false를 쓰는 방법이 22가지 있다고 지적함
- 숫자처럼 보이는 값도 파서가 다르게 받아들일 수 있음
07과08예시는 결과가[ 7, "08" ]처럼 달라질 수 있음을 보여줌- Kubernetes 클러스터가 일곱 번째까지는 배포되고 여덟 번째에서 실패하는 상황으로 풍자함
- 시간처럼 보이는 문자열도 자동 변환 대상이 됨
04:30은 사용자가 쓴 시각 문자열이 아니라 자정 이후 초 단위 값인16200으로 바뀔 수 있음- 문자열을 의도했다면
!!str 04:30처럼 명시해야 함
- YAML의 8진수 표기 차이도 혼란을 만듦
- YAML 1.1은
0666표기를 사용함 - YAML 1.2는
0o666표기를 사용함 - Kubernetes가 YAML 1.1을 쓰는 점을 “DevOps 통과의례”처럼 다룸
- YAML 1.1은
버전·SHA·문자열 처리 문제
- 패키지 버전은 부동소수점처럼 파싱될 수 있음
foo: 1.7과bar: 1.70은 같은 버전처럼 해석될 수 있음fizz: 1.7.0과buzz: 1.70.0은 다른 버전 문자열처럼 다뤄질 수 있음
- CI에서 쓰는 짧은 Git SHA도 안전하지 않을 수 있음
- 8자 SHA가 모두 숫자일 수 있음
${GIT_SHORT_SHA}를 따옴표 없이 넣은my.flaky_version은 문자열이 아닐 수 있음- 이 값은 약 98%는 문자열이고,
"${GIT_SHORT_SHA}"처럼 감싸면 100% 문자열이라고 제시됨
- Rust toolchain 사례도 참고 링크로 포함됨
CI와 인프라 설정에서 드러나는 비용
- GitHub Actions를 배우던 중 한 시간에 8번 커밋/푸시했고, 마지막 커밋 메시지가 “I don't really like yml”이었다는 사례가 포함됨
- SQL을 YAML로 쓴다면 어떤 모습인지 보여주는 예시도 있음
SELECT,FROM,WHERE EXISTS,AND,EQUALS,LT같은 SQL 구조가 YAML 중첩 구조로 바뀜- 짧은 SQL 표현이 길고 장황한 YAML 형태로 변하는 점을 풍자함
- CI 서비스마다 job과 step을 표현하는 방식도 제각각임
- Azure DevOps는
jobs아래job,steps,script형태를 사용함 - CircleCI는
jobs,job1,steps,checkout,run형태를 사용함 - “미래의 CI 시스템” 예시는 같은 작업이 또 다른 중첩 구조로 표현될 수 있음을 보여줌
- Azure DevOps는
- CloudFormation에서 CloudWatch
DashboardBody안에SEARCH함수를 넣는 경우, 이미 이스케이프된 내용을 다시 이스케이프하고 JSON 전체를 큰따옴표로 닫아야 하는 예시가 포함됨
실행 가능한 YAML과 파서 차이
- “executable yaml”이라는 표현은 보안 관련 YAML 파싱 문제와 연결됨
- YAML 파서 호환성 문제도 별도 자료로 다룸
- Every YAML parser is a custom YAML parser
- 파서별 동작이 같지 않을 수 있다는 점을 보여주는 자료로 배치됨
관련 자료와 대안
- YAML 문제를 다룬 참고 자료가 함께 묶여 있음
- Today we’re going to look at some general problems with the YAML format
- We replaced 1,000 lines of YAML with 10 structs and people started contributing again
- What if you used the same language and tools you use to define your app to define your infrastructure?
- A YAML file is almost always still 'valid' even if it is trunca
- the bug was that the YAML parser ignored the negative signs ... so negative GPS coordinates became positive ones
- There are 63 different ways to write multi-line strings in YAML
- StrictYAML Design Justifications
- YAML 중심 DevOps에 대한 대안으로 여러 도구와 접근이 나열됨
페이지 자체에 대한 반응
- Reddit 반응 모음은 페이지 디자인까지 비판 대상으로 삼음
- 웹사이트가 거대한 편집 가능한 텍스트 필드라는 반응이 있음
- 하이퍼링크가 클릭되지 않는다는 반응이 있음
- 페이지 전체 텍스트를 선택해 삭제할 수 있어 문제가 해결됐다는 농담이 있음
- YAML을 싫어하는 취지에는 동의하지만 웹사이트 디자인 결정은 의문이라는 반응이 있음
- 마지막 문구는 페이지가 의도적으로 “YAML만큼 사용 가능하게” 만들어졌다고 밝힘
댓글과 토론
Hacker News 의견들
-
내가 제일 좋아하는 골칫거리는 이거임:
07
08
결과가[ 7, "08" ]가 됨
8진수와 문자열에 대한 가정 때문임
이 가정이 세 단계 아래에서 템플릿으로 생성된 YAML 안에서 발견됐고, 우리 쪽 k8s 클러스터 전체 장애로 이어졌는데, 오직08클러스터만 망가졌음. 앞의 7개는 잘 돌아갔음- 이 웹사이트 만든 사람임. 이거 풀 리퀘스트로 보내주면 좋겠음
- 젠장, 요즘 개발자 대부분은 8진수나
0접두사로 쓰는 8진수 숫자 리터럴을 모를 것 같음
이 댓글 보고 웃긴 했지만, 2023년에 설정 파일에서 8진수를 쓰는 사람이 거의 없다는 점을 생각하면 이런 동작과 가정은 말이 안 됨. 16진수라면 몰라도, 10진수는 당연하고, 8진수는 좀 심함 - 이게 어떻게 맞는 동작일 수 있는지 이해가 안 감
- 그 가정을 “발견”했다는 건, 명세를 읽은 게 아니라 동작을 안다고 가정하고 쓰기 시작했다는 뜻인가?
저걸 생성한 쪽은 분명 라이브러리로 데이터를 직렬화하지 않았을 것임. 라이브러리를 썼다면 타입을 올바른 형식으로 변환했을 테니까
-
YAML에는 문제가 많지만, 진짜 핵심 문제는 설정 안에 로직을 넣으려는 데 있다고 봄
YAML은 데이터에만 쓰고 로직에 쓰지 않는다면 사람이 읽고 쓰기 좋은 데이터 형식 중 하나임
CI/CD에는 항상 어느 정도 로직이 있고, 순수 YAML만으로 끝나는 경우는 거의 없으며 이상한 템플릿까지 섞임. 차라리 진짜 프로그래밍 언어용 진짜 API를 제공하면 안 되나 싶음- 그건 YAML 문제가 아니라 YAML 오용에 가까움. 우발적인 튜링 완전성은 어디서나 문제임
15년 전 XML 기반 Ant를 썼을 때도 똑같은 문제가 있었고, 그건 XML 탓이 아니었음
YAML의 주된 문제는 타입 안전성 부족이라고 봄. 잘못된 들여쓰기, 키 오타, 불리언으로 파싱되는 문자열 같은 것들임
그 외에는 간결하고 다른 형식보다 문법 잡음이 훨씬 적어서 좋은 형식이라고 생각함. 그래서 사람들이 타입 안전한 YAML을 쓰고 이런 문제에 대해 즉각적이고 명확한 오류 메시지를 받도록 https://github.com/crdoconnor/strictyaml를 만들었음 - 내 경험상 언어가 할 수 있는 일이 많을수록, 사람들은 그것을 더 복잡한 방식으로 쓰게 됨
필요하다고 생각해서 추상화를 끌어들이기 때문임. 그래서 설정 형식으로 튜링 완전한 프로그래밍 언어를 쓰는 걸 항상 피함
AWS CDK를 JavaScript 디버거로 한 줄씩 따라가며 몇 시간을 보낸 적이 있음. 단순하고 멍청한 yaml/Json/뭐든 파일이었다면 그런 문제는 없었을 것임. 작은 프로젝트였고 복잡성이 필요하지 않았음
그래서 JS 도구 설정에서도 JS보다 JSON을 선호함. webpack 설정이 엉망이 되는 이유도 여기에 있음. 진짜 언어를 쓸 수 있게 되면 사람들의 “DRY 센서”가 발동해서 더 복잡하게 만듦
선언형이면 표준 관행을 따르기도 쉽고 도구 지원도 좋아짐. package.json이 실제로 build.gradle처럼 된다면 훨씬 더 나빠질 것임 - 실행 가능한 설정은 큰 이점을 줄 수 있음. Python은 명백한 선택지임
“제한이 강한 cgroup 안의 Python 인터프리터에서 스크립트를 실행하고, 그 결과CONFIG라는 딕셔너리가 나와야 한다”고 정하면 됨. 래퍼 로직이 그걸 설정 대상 프로그램에 편한 방식으로 직렬화하면 됨 - 나쁜 스키마 설계가 왜 YAML 탓이고 스키마 설계자 탓은 아닌지 모르겠음
helm의 복잡성이나 경직성을 불평하는 것과 비슷함. Helm 차트는 스스로 작성되지 않음. 문제를 이해하고 구현하기보다 불평하고 무시하는 쪽이 더 쉬워서 그런 것 같음 - 100% 동의함. 사람들이 YAML을 싫어한다고 할 때, 많은 경우 실제 뜻은 “YAML로 파이프라인을 기술하는 게 싫다”에 가깝다고 봄. 나도 그 느낌을 이해함
파일 형식으로서 YAML에는 장단점이 있음. 하지만 진짜 문제는 조건문, 반복문, 함수, 템플릿을 통한 클래스/하위 클래스 같은 것을 JSON 상당의 파일 형식으로 표현하려는 데 있음
YAML은 작은 설정에는 괜찮음. 하지만 어떤 종류든 제어 흐름이 필요해지는 순간, 벤더별 스파게티로 매우 빠르게 커짐
- 그건 YAML 문제가 아니라 YAML 오용에 가까움. 우발적인 튜링 완전성은 어디서나 문제임
-
YAML 안의 Jinja는 명백한 안티패턴이라고 봄
처음부터 충분한 프로그래밍 가능성을 설계하지 않았고, 나중에는 그 길을 택해 성공한 프로젝트들을 사람들이 따라 하면서 생긴 듯함
글에는 Dhall과 Jsonnet 같은 대안이 나오는데, 두 가지를 더 생각해볼 수 있음
첫째, 진짜 프로그래밍 언어용 설정 라이브러리를 만들고 이 라이브러리가 JSON 설정 파일을 생성하게 하는 것임. 그 JSON은 손으로 편집하는 대상이 아니라 검사 가능한 산출물로만 다룸. 사용자는 도구 지원을 받는 코드 형태의 설정을 버전 관리에 넣게 됨. 서버에서 바로 긴급 수정하기 어려워지는 건 단점이자 장점임
둘째, Starlark임. Bazel 빌드 시스템을 위해 처음 개발된 Python 파생의 비튜링 완전 언어임. 구현이 여러 개 있고 호환성이 얼마나 깊은지는 모르겠지만, Python 바인딩도 있음: https://github.com/caketop/python-starlark-go, https://github.com/inducer/starlark-pyo3- YAML 안의 Jinja가 안티패턴이라는 데 동의하지만, 특히 기본 블록/표현식 문자
{%와{{가 둘 다 YAML 문자라서 모든 사용 지점을 따옴표로 감싸야 한다는 점 때문임
GitHub Actions의${{나<%,<<같은 방식이 훨씬 낫다고 봄. 물론<<:가 YAML 문법이라는 위험은 있지만 합법적인 Jinja는 아님
YAML 안에 어떤 실행 가능한 것도 넣으면 안 된다는 뜻이라면, 그 배는 이미 떠났다고 봄. 사람들이 리터럴 부분을 기본으로 두고 가끔 실행 부분만 넣는 방식이 ASP/JSP/PHP처럼 콘텐츠를 만들기에 좋다는 걸 알아버렸기 때문임
이 스레드에서 형제 화염전을 시작하고 싶다면 HCL과for_each를 얘기하면 되겠지만, 적어도 여기서는 하지 않는 게 좋겠음 - 이게 Amazon이 CDK에서 택한 경로임. 어느 정도는 동작하지만, 사소하지 않은 일을 하려면 루브 골드버그 장치를 만드는 느낌이 강함
그중 얼마나 CDK 탓이고 얼마나 CloudFormation이 원래 별로인 탓인지는 모르겠음 - 동의함. 템플릿화된 YAML 작업이 너무 번거로워서 결국 그 때문에 Cels라는 도구를 만들었음: https://github.com/pacha/cels
Jsonnet과 Starlark를 좋아하지만, 실제로는 대부분의 사용 사례에서 새 프로그래밍 언어가 필요하지 않음. 보통은 기본 문서를 만들고 패치를 적용해 수정하고 싶을 뿐임. 그러면 모든 게 훨씬 단순해짐
순수 YAML을 쓰는 경험 자체는 그리 나쁘지 않음. 형식에 꽤 의심스러운 부분이 몇 가지 있지만 쓸 만함. 문제는 문서를 여러 환경에 맞추기 위해 추가해야 하는 해결책들의 복잡성에서 나타난다고 봄 - 이것 때문에 Ansible을 다시 다룰 생각만 해도 악몽임
예전에는 YAML 대신 쓸 수 있는 실제 Python DSL이 있었다고 들었는데 중단된 듯함. 그래서 이제 반복문과 if-then이 YAML로 길게 늘어진 끔찍한 덩어리가 되고, Jinja를 완전히 예측 불가능하게 해석함 jsonnet처럼 Starlark 코드를 실행해서 JSON이나 YAML을 생성할 수 있는 독립 실행형 도구가 있는지 궁금함
- YAML 안의 Jinja가 안티패턴이라는 데 동의하지만, 특히 기본 블록/표현식 문자
-
YAML 자체는 훌륭하다고 봄. 훌륭하지 않은 건 우리가 CD의 배포 부분을 너무 어렵게 만들어버린 점임
Azure DevOps 안의 우리 설정이 엄청 좋지는 않다는 건 인정하지만, 여러 팀이나 5~6명의 운영자가 이런 도구를 다뤄야 하는 조직이 있다는 사실은 놀라움. Google 같은 곳은 몰라도, 최대 동시 사용자 5만 명이거나 대개 그보다 훨씬 적은 평범한 엔터프라이즈에서는 과하다고 느낌
2000년대 초에는 부하 분산, 네트워킹 등 온갖 걸 정규직 0.25명도 안 되는 사람이 처리한 온프레미스 IIS에 엔터프라이즈 웹 앱을 배포하는 게, 지금의 “현대적” 설정에 같은 걸 배포하는 것보다 쉬웠음
물론 현대적인 파이프라인에는 장점이 있음. “내 컴퓨터에서는 되는데” 문제를 많이 넘어서고, 더 나은 승인 관문으로 품질 관리를 크게 높였음. 하지만 실제 배포는 2023년에도 악몽임
이건 실제 기술 회사나 좋은 전담 DevOps 팀이 있는 회사의 HN 프로그래머들에게는 문제가 아닐 수 있음. 하지만 비기술 엔터프라이즈 세계에서 CI/CD는 내 경력상 이렇게 나빴던 적이 없음
YAML을 탓할 수도 있고, 뭔가 하려면 너무 많은 YAML이 필요하고 템플릿이 어렵다는 점을 탓할 수도 있음. 하지만 내 생각엔 기술 문제보다 조직 문제가 훨씬 큼. 개발자가 인프라를 코드로 기술하는 일이 되지 않도록 CD 도구가 훨씬 더 자동화되어야 함
가능하다는 건 좋지만, 현실은 수백만 개발자에게 자신이 거의 이해하지 못할 수도 있는 인프라를 배포하라고 요구하는 것임. 컨테이너만 넘기고 네트워킹과 “서버 쪽 일”은 알아서 처리되길 바라지 않는 개발자를 본 적이 없음
그렇게 하지 않으면 아무도 작동 방식을 잘 모르는 VNET과 서브넷이 잔뜩 생기고, 개발자들이/x로 할 수 있다는 걸 몰라 조직이 큰돈을 잃게 됨- 클라우드는 새로운 메인프레임임
어떤 종류의 “작업 정의”를 오프라인에서 작성해 독점 공유 시스템에 제출하고, 큐에서 기다린 뒤, 내가 제어하지 못하는 시스템이 생성한 로그 파일을 받음. 독점 시스템 코드를 워크스테이션에서 로컬로 실행할 수 없어서 내부 반복 주기가 짧아도 수십 분, 길면 몇 시간이나 며칠이 됨
미리보기나 “what if” 모드, “dry run”도 없음. “테스트”라고 부르더라도 시스템이 하나뿐이라 사실상 프로덕션에서 작업함
진짜 문제는 YAML이 아님. 파이프라인이 신의 프로그래밍 언어로 스크립트되어도 상관없을 것임
중앙 시분할 메인프레임 대신 워크스테이션에서 소프트웨어를 개발하는 방식이 크게 인기를 얻은 이유는 내부 반복을 극적으로 빠르게 만들고, 프로덕션 환경과 격리하며, 제어권을 개발자 손에 돌려줬기 때문임
현세대 CI/CD 파이프라인은 대체로 그 모든 것을 되돌림
단일 머신 Kubernetes는 워크스테이션 기반 개발의 장점을 대부분 되살리지만, 아직 매우 새로운 시스템이라 성장통이 많음
관련 문제로, 혼자 클릭 작업으로 앱 하나를 운영하는 개발자에게는 훌륭한 해법이 있고, 수천 명 개발자를 위한 대규모 자동화를 하는 초대형 기업에도 훌륭한 해법이 있음. 하지만 그 중간, 몇 명의 엔터프라이즈 개발자가 수십 개 앱을 관리하는 영역은 그냥 혼돈임 - “내 컴퓨터에서는 되는데”를 완전히 넘어섰는지는 모르겠음
내 Docker 이미지에서는 여러 번 잘 동작했지만, 배포된 이미지에서는 깨진 적이 꽤 있었음
전체 빌드와 배포 파이프라인이 완전히 투명하고, 이미지 저장소에 대한 전체 접근 권한이 있고, 빌드 지시사항을 실제로 제어할 수 있어야만 통과 가능한 문제임. 이건 로컬 운영체제를 제어하는 것만큼이나 제한적이고, 다른 머신으로 옮길 때 코드가 깨졌던 조직 수만큼 실패할 것으로 봄 - 배포에서 뭐가 문제인지 모르겠음. 내가 설정한 것들은 그냥 커밋에 태그를 붙이고 푸시하면 그 커밋이 배포됐음
어떤 CI/CD 시스템에서도 그렇게 설정하는 건 꽤 직관적으로 보임
- 클라우드는 새로운 메인프레임임
-
모두가 한 가지 규칙만 보편적으로 존중한다면 평화를 유지할 해법이 있다고 봄: Python 생태계 밖에서는 YAML을 쓰지 말자
그러면 가독성을 정확성, 내구성, 유지보수성보다 우선하는 난해한 스크립팅 형식을 좋아하는 사람들은 탭 문자, 느슨한 타입, 난해한 문법을 계속 쓸 수 있음. 나머지 사람들은 그럴 필요가 없어짐. C 스타일 문법을 선호하는 사람들은 제정신을 유지할 수 있음
문제의 핵심을 이제야 짚은 것 같음. C 문법 개발자인 내게 문법적 공백은 순수한 광기임. 공백은 정보나 명령이 아니라 서식임. 좋은 서식은 도움이 되고 유용하며, 좋은 C 문법 개발자도 읽기 좋은 서식을 신경 씀
Python과 YAML에서는 서식이 지시 정보임. 기능하는 모든 코드가 읽기 쉬워진다는 장점은 있음. 하지만 왜 코드가 기능하려면 반드시 읽기 쉬워야 하나?
YAML 같은 동료와 일한다고 상상해보면 됨. 긴 메시지를 보냈더니 “뭐라고? 이건 말이 안 돼”라고 답함. 알고 보니 문단 사이에 빈 줄을 넣지 않아서 의미가 깨진 것임. 빈 줄을 다시 넣어 메시지를 보내면 그제야 읽을 수 있음. 문법적으로 정확한 서식 없이는 보낸 정보가 무의미했던 것임- 소프트웨어로서 코드의 또 다른 목적은 실행 가능함 외에도 읽을 수 있음임
서식을 잡는 방법은 수없이 많고, 나는 사람들이 코드를 쓸 때 린터를 쓰는 걸 선호함. 가능하면 내가 쓰는 것과 같은 린터였으면 좋겠음
그런 언어들은 표준 문법 구조를 강제함. 읽기 어려운 코드를 쓸 수 있는 방법이 줄어드니 좋은 일임 - 보통 의미 있는 공백은 철학적이거나 종교적인 문제라고 여김. 좋아하는 사람도 있고 싫어하는 사람도 있으며, 양쪽 모두 선호를 합리화하지만 결국 강한 취향 문제라는 식임
그런데 이제는 그 차이가 철학이 아니라 도구 문제라고 생각하게 됨. 어떤 도구, 예를 들어 텍스트 편집기나 이메일 프로그램은 의미 있는 공백을 잘 지원하고, 어떤 도구는 그렇지 않음
내가 쓰는 텍스트 편집기들은 모두 공백과 탭 문자를 표시하도록 설정되어 있고, 둘을 다르게 보여줌. 보통 희미한 점과 희미한 대시 같은 식임. 익숙해서 전혀 거슬리지 않음
내 관점에서 코드는 임의의 텍스트가 아님. 책에는 쓰지 않을 고정폭 글꼴을 쓰고, 색으로 구문을 구분함. 공백을 보이게 만들지 않을 이유도 없음
여전히 의미 있는 공백이 없는 언어를 더 선호하긴 하지만, 그런 언어를 싫어하지는 않음. 내게는 전혀 문제가 안 됨
하지만 좋아하는 도구가 의미 있는 공백을 잘 지원하지 않거나, 공백을 보이게 하지 않거나, 심지어 가변폭 글꼴로 코딩한다면, 의미 있는 공백을 열렬히 싫어하고 순수한 광기로 볼 수밖에 없음 - C 배경이라 나도 공백은 정보나 명령이 아니라는 같은 생각을 했음. Python 초창기에는 그 때문에 약간 깔보기도 했음
생각을 바꾼 계기는 의외로 CoffeeScript를 쓰면서였음. JavaScript를 별로 좋아하지 않는데, CoffeeScript를 쓰는 느낌은 Crockford의 The Good Parts를 정제한 것 같았음. 나쁜 부분을 실수로 만들어낼 수 없었음
게다가 들여쓰기가 코드가 되는 방식이 꽤 쾌적했음. 유일한 불편은 Vi에서 여는 중괄호나 닫는 중괄호에%를 눌러 블록의 반대쪽 끝을 찾을 수 없다는 점임. 반대로 들여쓰기 덕분에 코드가 이상해 보이면 실제로 이상한 경우가 많았음
그래도 Python은 아직 많이 배우지 않았음. 요즘은 TypeScript를 쓰지만, 언젠가 CoffeeTypeScript가 나온다면… - TOML은 표준 라이브러리에 있는데 YAML은 없다는 게 좀 이상함. 그리고 TOML은 못생김
- Kubernetes 커뮤니티가 흥미로운 눈빛으로 바라보고 있음
- 소프트웨어로서 코드의 또 다른 목적은 실행 가능함 외에도 읽을 수 있음임
-
그래서 직접 BCL이라는 형식을 만들기 시작했음: https://github.com/wkhere/bcl
모든 YAML 사용 사례에 즉시 도움이 되지는 않겠지만, 적어도 Terraform 같은 스타일로 리소스를 정의하는 더 멋진 방식이 될 수 있음. 실제로 내부 프로젝트 하나에서 HCL 대체제로 이미 도움이 되고 있고, 그게 만들게 된 마지막 동기였음
더 크게 보면 Kubernetes에서 YAML이 어디에나 있는 문제를 어떻게 도울지 모르겠음. 내$daily_job문제의 절반 이상은 여러 출처에서 최종 Helm 차트를 합치는 일이 너무 조악하다는 데 있음
Helm이 본질적으로 나쁜 도구라거나 우리 회사가 Helm을 꽤 나쁜 방식으로 골랐다는 뜻은 아님. 모두가 상황을 고려해 최선을 다하고 있다고 봄
하지만 의미 있는 공백이 있는 텍스트 템플릿을 조작하는 건 너무 오류가 나기 쉽고, 오류 발견도 너무 늦음. Kubernetes는 YAML이 얼마나 멋진지 증명하려 하기보다, C 스타일 문법 기반의 맞춤 형식을 썼다면 훨씬 나았을 것이라고 봄. 특히 YAML은 멋지지도 않음- YAML에는 좋은 기능이 두 가지 있음. 여러 줄 문자열과 YAML이 JSON의 상위집합이라는 점임
JSON을 생성하는 어떤 것이든 YAML 생성에 쓸 수 있음
Nickel은 JSON으로 평가될 수 있음: https://nickel-lang.org/ - 이 Nixcon 발표가 인상적이었음
https://youtu.be/SEA1Qm8K4gY?feature=shared - ucl은 봤는지 궁금함: https://github.com/vstakhov/libucl
꽤 비슷해 보임
- YAML에는 좋은 기능이 두 가지 있음. 여러 줄 문자열과 YAML이 JSON의 상위집합이라는 점임
-
이건 내부 플랫폼 효과임. 애플리케이션이 커질수록 설정도 확장되다가 결국 프로그래밍 언어가 되는데, 버그가 많고 명세가 부족하고 사용성이 끔찍한 언어가 됨
설정 파산을 선언하고 새 설정 형식을 고름. 그리고 반복됨
물론 형식 자체도 책임이 없지는 않음. 유연할수록 나쁜 프로그래밍 언어로 재활용되기 쉬움
이 실수를 반복해서 저지른 뒤, 요즘은 기본 설정에는 가능한 한 가장 단순한 설정 형식을 고를 것임..ini조차 너무 강력할 수 있음. 더 복잡한 “설정”은 실제 프로그래밍 언어, 가능하면 애플리케이션이 작성된 언어에 위임하겠음 -
“YAML은 별로다” 예시의 압도적 다수는 이상한 리터럴을 전부 따옴표로 감싸면 해결됨
YAML이 때때로 짜증나는 건 맞음. 예를 들어 맵의 리스트는 금방 이상해지고, 의미 있는 공백은 거의 반드시 언젠가 발목을 잡음. 하지만 이런 글들은 좋게 봐도 좀 불성실해 보임- 그런데 그런 예시들 중 따옴표를 쓰는 경우는 없고, 도구들도 그렇게 해주지 않음
YAML 생태계 전체가 값을 따옴표 없이 쓰도록 유도함. 대개는 잘 동작하다가, 프로덕션에서 걸려 넘어질 만큼만 가끔 깨짐
- 그런데 그런 예시들 중 따옴표를 쓰는 경우는 없고, 도구들도 그렇게 해주지 않음
-
EDN은 Clojure의 부분집합임: https://github.com/edn-format/edn
명확하고, 스트리밍 가능하고, 확장 가능하며, 공백에 민감하지 않음. 다만 가독성을 위한 서식 관례는 있음- 리스트와 집합을 명시적으로 구분하는 데이터 형식은 처음 봤고, 그건 좋음
하지만 리스트와 벡터의 의미 차이가 무엇인지는 잘 모르겠음. 내 머릿속에서 배열과 연결 리스트는 코드 안 자료구조의 구현 세부사항이지 데이터 형식의 차이는 아님 - 대안들보다 훨씬 나음. Clojure 생태계 밖에서도 쓰이기 시작하길 정말 바람
- 정확히는 공백 비의존적이라고 하긴 어려움. 요소 경계나 구분을 위해 공백이 필요하기 때문임
그래도 의미론적 들여쓰기 장난은 전혀 없음. 쉼표가 공백으로 간주되고 필요 없다는 점은 아름다움
- 리스트와 집합을 명시적으로 구분하는 데이터 형식은 처음 봤고, 그건 좋음
-
학생들이 이러닝 플랫폼으로 과제를 제출하면, 우리는 모든 제출물을 꽤 큰 XML 파일로 받음
제출물을 읽고, 정적 분석과 예제 실행에 넘긴 뒤, 과제별로 모든 제출물, 채점 힌트, 코멘트와 점수 입력 필드 등이 들어간 YAML 파일을 씀
그런 다음 YAML 파일에서 markdown+판독(Pandoc)을 거쳐 보고서, 통계, 피드백 PDF를 생성함
우리에게 YAML은 아주 잘 맞음. Markdown 문법으로 추가 피드백을 넣기 쉽기 때문임. 예를 들어 올바르게 들여쓴- you missed a \NOT` here` 같은 식임
블록 텍스트의 여러 이스케이프 방식 덕분에, 학생들이 다양한 SQL 구분자를 쓰더라도 SQL 제출물을 이스케이프 문자 없이 보기 좋게 출력할 수 있음
전부 일반 텍스트라 텍스트 편집기만 쓰고, git에 저장해 채점 책임성을 확보함. 모든 것을 기계가 읽을 수 있게 보관하므로 과거 제출물에 새 정적 분석 도구를 테스트할 수도 있음
하지만 CI 파이프라인과 홈 자동화 설정도 YAML로 써야 하다 보니 그 고통은 이해함- 임베드된 텍스트의 들여쓰기 제거는 아마 YAML이 가진 가장 좋은 기능일 것임
TOML에서는 여러 줄 문자열 들여쓰기를 포기해서 가독성을 낮추거나, 매 줄 끝에 백슬래시를 넣어야 함. 어느 쪽도 이상적이지 않음
그래서 Markdown이나 다른 텍스트 형식을 포함해야 하는 DSL이나 설정에는 YAML이 꽤 좋고, TOML 같은 것보다 우위를 가짐
하지만 “YAML 피로감”의 모든 책임을 DSL의 운반 형식으로 YAML을 고른 CI와 DevOps 도구들에만 돌리지는 않겠음. 원 글이 잘 정리했듯 YAML 자체에도 큰 문제가 있음
유명한 “Norway 문제”는 YAML 1.2에서 해결됐고, 선행 0을 8진수로 파싱하는 문제도 YAML 1.2에서 해결됐음. 숫자, 날짜, 시간 등에 대한 과도한 타입 강제 변환은 혼란스러울 수 있음. 여러 줄 문자열 처리 모드도 꽤 헷갈릴 수 있음. 안전하지 않은 직렬화는 현대 파서에서는 문제가 아니지만, Ruby, Python, Java처럼 동적 기능이 있는 오래된 언어에서 YAML을 쓸 때는 조심해야 함
이 모든 것은 YAML 명세 자체의 문제임
- 임베드된 텍스트의 들여쓰기 제거는 아마 YAML이 가진 가장 좋은 기능일 것임