- 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만큼 사용 가능하게” 만들어졌다고 밝힘