YAML Zen์„ ์œ„ํ•œ 10๋‹จ๊ณ„

์šฐ๋ฆฌ ๋ชจ๋‘๋Š” Ansible์„ ์ข‹์•„ํ•˜์ง€๋งŒ Ansible์€ YAML์ž…๋‹ˆ๋‹ค. ๊ตฌ์„ฑ ํŒŒ์ผ์—๋Š” ๊ฐ’ ๋ชฉ๋ก, ๋งค๊ฐœ๋ณ€์ˆ˜-๊ฐ’ ์Œ, INI ํŒŒ์ผ, YAML, JSON, XML ๋“ฑ ๋‹ค์–‘ํ•œ ํ˜•์‹์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ทธ ์ค‘์—์„œ๋„ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์ด์œ ๋กœ ์ธํ•ด YAML์€ ํŠนํžˆ ์–ด๋ ค์šด ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ ๊ณ„์ธต์  ๊ฐ’ ์ž‘์—…์„ ์œ„ํ•œ ์ƒ์พŒํ•œ ๋ฏธ๋‹ˆ๋ฉ€๋ฆฌ์ฆ˜๊ณผ ์ธ์ƒ์ ์ธ ๊ธฐ๋Šฅ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  YAML ๊ตฌ๋ฌธ์€ ๋“ค์—ฌ์“ฐ๊ธฐ์— ๋Œ€ํ•œ Python๊ณผ ์œ ์‚ฌํ•œ ์ ‘๊ทผ ๋ฐฉ์‹์œผ๋กœ ์ธํ•ด ์งœ์ฆ์Šค๋Ÿฌ์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

YAML Zen์„ ์œ„ํ•œ 10๋‹จ๊ณ„

YAML์ด ๋‹น์‹ ์„ ํ™”๋‚˜๊ฒŒ ํ•œ๋‹ค๋ฉด ๊ทธ๋ ‡๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ทธ๋ ‡๊ฒŒ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค! โ€“ ์ขŒ์ ˆ๊ฐ์„ ํ—ˆ์šฉ ๊ฐ€๋Šฅํ•œ ์ˆ˜์ค€์œผ๋กœ ์ค„์ด๊ณ  YAML๊ณผ ์‚ฌ๋ž‘์— ๋น ์ง€๋ ค๋ฉด ๋‹ค์Œ 10๋‹จ๊ณ„๋ฅผ ๋”ฐ๋ฅด์„ธ์š”. ์ด ๋ชฉ๋ก์— ๊ฑธ๋งž๊ฒŒ ์šฐ๋ฆฌ์˜ XNUMX๊ฐ€์ง€ ํŒ์€ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋ฒˆํ˜ธ๊ฐ€ ๋งค๊ฒจ์ ธ ์žˆ์œผ๋ฉฐ ๋งˆ์Œ๋Œ€๋กœ ๋ช…์ƒ๊ณผ ์˜์  ์ˆ˜ํ–‰์„ ์ถ”๊ฐ€ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค ๐Ÿ˜‰

0. ํŽธ์ง‘๊ธฐ๋ฅผ ์ž‘๋™ํ•˜๊ฒŒ ๋งŒ๋“œ์„ธ์š”

์–ด๋–ค ํ…์ŠคํŠธ ํŽธ์ง‘๊ธฐ๋ฅผ ์‚ฌ์šฉํ•˜๋“  ์ƒ๊ด€์—†์ด YAML ์ž‘์—…์„ ์œ„ํ•œ ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ํ•˜๋‚˜ ์ด์ƒ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์—†๋Š” ๊ฒฝ์šฐ ์ฆ‰์‹œ ์ฐพ์•„ ์„ค์น˜ํ•˜์‹ญ์‹œ์˜ค. ๊ฒ€์ƒ‰ ๋ฐ ์„ค์ •์— ์†Œ์š”๋œ ์‹œ๊ฐ„์€ YAML์„ ํŽธ์ง‘ํ•ด์•ผ ํ•  ๋•Œ๋งˆ๋‹ค ์—ฌ๋Ÿฌ ๋ฒˆ ๋ณด์ƒ์„ ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ํŽธ์ง‘์ž ์›์ž ๊ธฐ๋ณธ์ ์œผ๋กœ YAML์„ ์ง€์›ํ•˜์ง€๋งŒ GNU Emacs์˜ ๊ฒฝ์šฐ ์ถ”๊ฐ€ ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. yaml ๋ชจ๋“œ.

YAML Zen์„ ์œ„ํ•œ 10๋‹จ๊ณ„

YAML ๋ชจ๋“œ์˜ Emacs ๋ฐ ๊ณต๋ฐฑ ํ‘œ์‹œ.

์ฆ๊ฒจ ์‚ฌ์šฉํ•˜๋Š” ํŽธ์ง‘๊ธฐ์— YAML ๋ชจ๋“œ๊ฐ€ ์—†์œผ๋ฉด ์„ค์ • ์ž‘์—…์„ ํ†ตํ•ด ์ผ๋ถ€ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ํ‘œ์ค€ GNOME ํ…์ŠคํŠธ ํŽธ์ง‘๊ธฐ Gedit์—๋Š” YAML ๋ชจ๋“œ๊ฐ€ ์—†์ง€๋งŒ ๊ธฐ๋ณธ์ ์œผ๋กœ YAML ๊ตฌ๋ฌธ์„ ๊ฐ•์กฐ ํ‘œ์‹œํ•˜๊ณ  ๋“ค์—ฌ์“ฐ๊ธฐ ์ž‘์—…์„ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

YAML Zen์„ ์œ„ํ•œ 10๋‹จ๊ณ„

Gedit์—์„œ ๋“ค์—ฌ์“ฐ๊ธฐ๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

ํ”Œ๋Ÿฌ๊ทธ์ธ ์„œ๋ž ๊ณต๊ฐ„ Gedit์˜ ๊ฒฝ์šฐ ๊ณต๋ฐฑ์„ ์ ์œผ๋กœ ํ‘œ์‹œํ•˜์—ฌ ๋“ค์—ฌ์“ฐ๊ธฐ ์ˆ˜์ค€์˜ ๋ชจํ˜ธ์„ฑ์„ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

์ฆ‰, ์ข‹์•„ํ•˜๋Š” ํŽธ์ง‘๊ธฐ์— ๋Œ€ํ•ด ๋ฐฐ์šฐ๋Š” ๋ฐ ์‹œ๊ฐ„์„ ํˆฌ์žํ•˜์„ธ์š”. ๊ทธ ๋˜๋Š” ๊ทธ์˜ ๊ฐœ๋ฐœ ์ปค๋ฎค๋‹ˆํ‹ฐ๊ฐ€ YAML ์ž‘์—…์„ ์œ„ํ•ด ๋ฌด์—‡์„ ์ œ๊ณตํ•˜๋Š”์ง€ ์•Œ์•„๋ณด๊ณ  ํ•ด๋‹น ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค. ๋‹น์‹ ์€ ํ™•์‹คํžˆ ๊ทธ๊ฒƒ์„ ํ›„ํšŒํ•˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

1. ๋ฆฐํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”

์ด์ƒ์ ์œผ๋กœ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์™€ ๋งˆํฌ์—… ์–ธ์–ด๋Š” ์˜ˆ์ธก ๊ฐ€๋Šฅํ•œ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ปดํ“จํ„ฐ๋Š” ์˜ˆ์ธก ๊ฐ€๋Šฅ์„ฑ์— ๋›ฐ์–ด๋‚˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฆฐํ…Œ๋ผ. 40๋…„ ๋™์•ˆ ์กด์žฌํ–ˆ์ง€๋งŒ ์—ฌ์ „ํžˆ YAML ๋ฆฐํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด yamllint๋ฅผ ์‚ฌ์šฉํ•ด ๋ณผ ์‹œ๊ฐ„์ž…๋‹ˆ๋‹ค.

์„ค์น˜ ์–Œ๋ฆฐํŠธ ํ‘œ์ค€ Linux ํŒจํ‚ค์ง€ ๊ด€๋ฆฌ์ž๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, Red Hat Enterprise Linux 8 ๋˜๋Š” ํŽ˜๋„๋ผ ๊ทธ๊ฒƒ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ด๋ฃจ์–ด์กŒ์Šต๋‹ˆ๋‹ค :

$ sudo dnf install yamllint

๊ทธ๋Ÿฐ ๋‹ค์Œ yamllint๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ํ™•์ธํ•  YAML ํŒŒ์ผ์„ ์ „๋‹ฌํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์˜ค๋ฅ˜๊ฐ€ ์žˆ๋Š” ํŒŒ์ผ์„ linter์— ์ „๋‹ฌํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

$ yamllint errorprone.yaml
errorprone.yaml
23:10     error    syntax error: mapping values are not allowed here
23:11     error    trailing spaces  (trailing-spaces)

์™ผ์ชฝ์˜ ์ˆซ์ž๋Š” ์‹œ๊ฐ„์ด ์•„๋‹ˆ๋ผ ์˜ค๋ฅ˜ ์ขŒํ‘œ(ํ–‰ ๋ฐ ์—ด ๋ฒˆํ˜ธ)์ž…๋‹ˆ๋‹ค. ์˜ค๋ฅ˜์— ๋Œ€ํ•œ ์„ค๋ช…์œผ๋กœ๋Š” ์•„๋ฌด ๊ฒƒ๋„ ์•Œ๋ ค์ฃผ์ง€ ์•Š์„ ์ˆ˜ ์žˆ์ง€๋งŒ ์˜ค๋ฅ˜๊ฐ€ ์–ด๋””์— ์žˆ๋Š”์ง€ ์ •ํ™•ํžˆ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ์—์„œ ์ด ๋ถ€๋ถ„์„ ๋ณด๋ฉด ๋ชจ๋“  ๊ฒƒ์ด ๋ช…ํ™•ํ•ด์งˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

yamllint๊ฐ€ ํŒŒ์ผ์—์„œ ์˜ค๋ฅ˜๋ฅผ ์ฐพ์ง€ ๋ชปํ•˜๋ฉด ํ™”๋ฉด์— ์•„๋ฌด๊ฒƒ๋„ ์ธ์‡„๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์นจ๋ฌต์ด ๋‘๋ ต๊ณ  ์ข€ ๋” ํ”ผ๋“œ๋ฐฑ์„ ์›ํ•  ๊ฒฝ์šฐ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ด์ค‘ ์•ฐํผ์ƒŒ๋“œ(&&)๋ฅผ ํ†ตํ•ด ์กฐ๊ฑด๋ถ€ echo ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์—ฌ linter๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

$ yamllint perfect.yaml && echo "OK"
OK

POSIX์—์„œ๋Š” ์ด์ „ ๋ช…๋ น์ด 0์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒฝ์šฐ์—๋งŒ ์ด์ค‘ ์•ฐํผ์ƒŒ๋“œ๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  yamllint๋Š” ๋ฐœ๊ฒฌ๋œ ์˜ค๋ฅ˜ ์ˆ˜๋งŒ ๋ฐ˜ํ™˜ํ•˜๋ฏ€๋กœ ์ด ์ „์ฒด ์กฐ๊ฑด๋ถ€ ๊ตฌ์„ฑ์ด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

2. YAML์ด ์•„๋‹Œ Python์œผ๋กœ ์ž‘์„ฑ

YAML์ด ์ •๋ง๋กœ ๋‹น์‹ ์„ ํ™”๋‚˜๊ฒŒ ํ•œ๋‹ค๋ฉด ๋ฌธ์ž ๊ทธ๋Œ€๋กœ ์“ฐ์ง€ ๋งˆ์‹ญ์‹œ์˜ค. YAML์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ดํ•ดํ•˜๋Š” ์œ ์ผํ•œ ํ˜•์‹์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด ๊ฒฝ์šฐ์—๋„ YAML ํŒŒ์ผ์„ ์ƒ์„ฑํ•  ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค. ๋‹น์‹ ์ด ์ข‹์•„ํ•˜๋Š” ๊ฒƒ์„ ์“ด ๋‹ค์Œ ๋ณ€ํ™˜ํ•˜์‹ญ์‹œ์˜ค. ์˜ˆ๋ฅผ ๋“ค์–ด Python์„ ์œ„ํ•œ ํ›Œ๋ฅญํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ํ”ผ์–Œ ๋ณ€ํ™˜ ๋ฐฉ๋ฒ•์—๋Š” ์ž์ฒด ๋ณ€ํ™˜๊ณผ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ†ตํ•œ ๋ณ€ํ™˜์˜ ๋‘ ๊ฐ€์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์ž๊ธฐ ์ „ํ™˜

์ด ๊ฒฝ์šฐ ๋ฐ์ดํ„ฐ ํŒŒ์ผ์€ YAML์„ ์ƒ์„ฑํ•˜๋Š” Python ์Šคํฌ๋ฆฝํŠธ์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฐฉ๋ฒ•์€ ์ž‘์€ ๋ฐ์ดํ„ฐ ์„ธํŠธ์— ๊ฐ€์žฅ ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค. JSON ๋ฐ์ดํ„ฐ๋ฅผ Python ๋ณ€์ˆ˜์— ์ž‘์„ฑํ•˜๊ณ , ์•ž์— import ์ง€์‹œ๋ฌธ์„ ์ถ”๊ฐ€ํ•˜๊ณ , ํŒŒ์ผ ๋์— ์„ธ ์ค„์„ ์ถ”๊ฐ€ํ•˜์—ฌ ์ถœ๋ ฅ์„ ๊ตฌํ˜„ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

#!/usr/bin/python3	
import yaml 

d={
"glossary": {
  "title": "example glossary",
  "GlossDiv": {
	"title": "S",
	"GlossList": {
	  "GlossEntry": {
		"ID": "SGML",
		"SortAs": "SGML",
		"GlossTerm": "Standard Generalized Markup Language",
		"Acronym": "SGML",
		"Abbrev": "ISO 8879:1986",
		"GlossDef": {
		  "para": "A meta-markup language, used to create markup languages such as DocBook.",
		  "GlossSeeAlso": ["GML", "XML"]
		  },
		"GlossSee": "markup"
		}
	  }
	}
  }
}

f=open('output.yaml','w')
f.write(yaml.dump(d))
f.close

์ด์ œ ์ด ํŒŒ์ผ์„ Python์—์„œ ์‹คํ–‰ํ•˜๊ณ  output.yaml ํŒŒ์ผ์„ ์–ป์Šต๋‹ˆ๋‹ค.

$ python3 ./example.json
$ cat output.yaml
glossary:
  GlossDiv:
	GlossList:
	  GlossEntry:
		Abbrev: ISO 8879:1986
		Acronym: SGML
		GlossDef:
		  GlossSeeAlso: [GML, XML]
		  para: A meta-markup language, used to create markup languages such as DocBook.
		GlossSee: markup
		GlossTerm: Standard Generalized Markup Language
		ID: SGML
		SortAs: SGML
	title: S
  title: example glossary

์ด๋Š” ์™„๋ฒฝํ•˜๊ฒŒ ์œ ํšจํ•œ YAML์ด์ง€๋งŒ yamllint๋Š” -๋กœ ์‹œ์ž‘ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒฝ๊ณ ๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ๊ธ€์Ž„, ์ด๊ฒƒ์€ ์ˆ˜๋™์œผ๋กœ ์‰ฝ๊ฒŒ ์ˆ˜์ •๋˜๊ฑฐ๋‚˜ Python ์Šคํฌ๋ฆฝํŠธ์—์„œ ์•ฝ๊ฐ„ ์ˆ˜์ •๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ†ตํ•œ ๋ณ€ํ™˜

์ด ๊ฒฝ์šฐ ๋จผ์ € JSON์œผ๋กœ ์ž‘์„ฑํ•œ ๋‹ค์Œ ๋ณ€ํ™˜๊ธฐ๋ฅผ ๋ณ„๋„์˜ Python ์Šคํฌ๋ฆฝํŠธ๋กœ ์‹คํ–‰ํ•˜์—ฌ YAML์„ ์ถœ๋ ฅ์œผ๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ด์ „ ๋ฐฉ๋ฒ•์— ๋น„ํ•ด ์ด ๋ฐฉ๋ฒ•์€ ๋ณ€ํ™˜์ด ๋ฐ์ดํ„ฐ์™€ ๋ถ„๋ฆฌ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํ™•์žฅ์„ฑ์ด ๋” ์ข‹์Šต๋‹ˆ๋‹ค.

๋จผ์ € JSON ํŒŒ์ผ example.json์„ ์ƒ์„ฑํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ์—์„œ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. json.org:

{
	"glossary": {
	  "title": "example glossary",
	  "GlossDiv": {
		"title": "S",
		"GlossList": {
		  "GlossEntry": {
			"ID": "SGML",
			"SortAs": "SGML",
			"GlossTerm": "Standard Generalized Markup Language",
			"Acronym": "SGML",
			"Abbrev": "ISO 8879:1986",
			"GlossDef": {
			  "para": "A meta-markup language, used to create markup languages such as DocBook.",
			  "GlossSeeAlso": ["GML", "XML"]
			  },
			"GlossSee": "markup"
			}
		  }
		}
	  }
	}

๊ทธ๋Ÿฐ ๋‹ค์Œ ๊ฐ„๋‹จํ•œ ๋ณ€ํ™˜๊ธฐ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  json2yaml.py๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ์ด ์Šคํฌ๋ฆฝํŠธ๋Š” YAML ๋ฐ JSON Python ๋ชจ๋“ˆ์„ ๋ชจ๋‘ ๊ฐ€์ ธ์˜ค๊ณ , ์‚ฌ์šฉ์ž ์ง€์ • JSON ํŒŒ์ผ์„ ๋กœ๋“œํ•˜๊ณ , ๋ณ€ํ™˜์„ ์ˆ˜ํ–‰ํ•˜๊ณ , ๋ฐ์ดํ„ฐ๋ฅผ output.yaml ํŒŒ์ผ์— ์”๋‹ˆ๋‹ค.

#!/usr/bin/python3
import yaml
import sys
import json

OUT=open('output.yaml','w')
IN=open(sys.argv[1], 'r')

JSON = json.load(IN)
IN.close()
yaml.dump(JSON, OUT)
OUT.close()

์ด ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹œ์Šคํ…œ ๊ฒฝ๋กœ์— ์ €์žฅํ•˜๊ณ  ํ•„์š”์— ๋”ฐ๋ผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

$ ~/bin/json2yaml.py example.json

3. ๋งŽ์ด, ์ž์ฃผ ๋ถ„์„ํ•˜๋ผ

๋•Œ๋กœ๋Š” ๋‹ค๋ฅธ ๊ฐ๋„์—์„œ ๋ฌธ์ œ๋ฅผ ๋ณด๋Š” ๊ฒƒ์ด ์œ ์šฉํ•  ๋•Œ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. YAML์—์„œ ๋ฐ์ดํ„ฐ ๊ฐ„์˜ ๊ด€๊ณ„๋ฅผ ํ‘œํ˜„ํ•˜๋Š” ๋ฐ ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ์ผ์‹œ์ ์œผ๋กœ ์ข€ ๋” ์นœ์ˆ™ํ•œ ๊ฒƒ์œผ๋กœ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ์‚ฌ์ „ ๋ชฉ๋ก์ด๋‚˜ JSON ์ž‘์—…์— ์ต์ˆ™ํ•˜๋‹ค๋ฉด ๋Œ€ํ™”ํ˜• Python ์…ธ์—์„œ ๋‹จ ๋‘ ๊ฐœ์˜ ๋ช…๋ น๋งŒ ์‚ฌ์šฉํ•˜์—ฌ YAML์„ JSON์œผ๋กœ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. YAML ํŒŒ์ผ mydata.yaml์ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

$ python3
>>> f=open('mydata.yaml','r')
>>> yaml.load(f)
{'document': 34843, 'date': datetime.date(2019, 5, 23), 'bill-to': {'given': 'Seth', 'family': 'Kenlon', 'address': {'street': '51b Mornington Roadn', 'city': 'Brooklyn', 'state': 'Wellington', 'postal': 6021, 'country': 'NZ'}}, 'words': 938, 'comments': 'Good article. Could be better.'}

์ด ์ฃผ์ œ์— ๋Œ€ํ•œ ๋‹ค๋ฅธ ๋งŽ์€ ์˜ˆ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์˜จ๋ผ์ธ ๋ณ€ํ™˜๊ธฐ์™€ ๋กœ์ปฌ ํŒŒ์„œ๊ฐ€ ๋งŽ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ฐ์ดํ„ฐ์— ์ดํ•ดํ•  ์ˆ˜ ์—†๋Š” ๋’ค์ฃฝ๋ฐ•์ฃฝ๋งŒ ๋ณด์ด๋Š” ๊ฒฝ์šฐ ์ฃผ์ €ํ•˜์ง€ ๋ง๊ณ  ๋ฐ์ดํ„ฐ ํ˜•์‹์„ ๋‹ค์‹œ ์ง€์ •ํ•˜์‹ญ์‹œ์˜ค.

4. ์‚ฌ์–‘ ์ฝ๊ธฐ

์˜ค๋žœ ํœด์‹ ํ›„ YAML๋กœ ๋Œ์•„์˜ค์‹œ๋ฉด ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. yaml.org ๊ทธ๋ฆฌ๊ณ  ์ŠคํŽ™(specs)์„ ๋‹ค์‹œ ์ฝ์–ด๋ณด์„ธ์š”. YAML์— ์–ด๋ ค์›€์ด ์žˆ์ง€๋งŒ ์‚ฌ์–‘์— ๋„๋‹ฌํ•˜์ง€ ๋ชปํ–ˆ๋‹ค๋ฉด ์ด์ œ ์ด ์ƒํ™ฉ์„ ์ˆ˜์ •ํ•ด์•ผ ํ•  ๋•Œ์ž…๋‹ˆ๋‹ค. ์‚ฌ์–‘์€ ๋†€๋ผ์šธ ์ •๋„๋กœ ์ž‘์„ฑํ•˜๊ธฐ ์‰ฝ๊ณ  ๊ตฌ๋ฌธ ์š”๊ตฌ ์‚ฌํ•ญ์€ ๋‹ค์Œ์˜ ๋งŽ์€ ์˜ˆ์ œ๋ฅผ ํ†ตํ•ด ์„ค๋ช…๋ฉ๋‹ˆ๋‹ค. ์ œ 6 ์žฅ.

5. ์˜์‚ฌ ๊ตฌ์„ฑ

์ฑ…์ด๋‚˜ ๊ธฐ์‚ฌ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ ์ตœ์†Œํ•œ ๋ชฉ์ฐจ ํ˜•ํƒœ๋กœ ๋จผ์ € ์˜ˆ๋น„ ๊ฐœ์š”๋ฅผ ๊ทธ๋ฆฌ๋Š” ๊ฒƒ์ด ํ•ญ์ƒ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. YAML๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ YAML ํŒŒ์ผ์— ์–ด๋–ค ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋กํ•ด์•ผ ํ•˜๋Š”์ง€ ์•Œ๊ณ  ์žˆ์ง€๋งŒ ์ด๋ฅผ ์„œ๋กœ ์—ฐ๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์‹ค์ œ๋กœ ์ดํ•ดํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ YAML์„ ์กฐ๊ฐํ•˜๊ธฐ ์ „์— ์˜์‚ฌ ๊ตฌ์„ฑ์„ ๊ทธ๋ฆฝ๋‹ˆ๋‹ค.

์˜์‚ฌ ๊ตฌ์„ฑ์€ ๊ตฌ์กฐ๋‚˜ ๋“ค์—ฌ์“ฐ๊ธฐ, ๋ถ€๋ชจ-์ž์‹ ๊ด€๊ณ„, ์ƒ์† ๋ฐ ์ค‘์ฒฉ์— ๋Œ€ํ•ด ๊ฑฑ์ •ํ•  ํ•„์š”๊ฐ€ ์—†๋Š” ์˜์‚ฌ ์ฝ”๋“œ์™€ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—์„œ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค. ๋จธ๋ฆฌ ์†์— ๋ฐ์ดํ„ฐ๊ฐ€ ๋‚˜ํƒ€๋‚  ๋•Œ๋งˆ๋‹ค ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜๋ณตํ•ด์„œ ๊ทธ๋ฆฝ๋‹ˆ๋‹ค.

YAML Zen์„ ์œ„ํ•œ 10๋‹จ๊ณ„

์˜์‚ฌ ๊ตฌ์„ฑ ๋ชฉ๋ก ํ”„๋กœ๊ทธ๋ž˜๋จธ(Martin ๋ฐ Tabitha) ๋ฐ ํ•ด๋‹น ๊ธฐ์ˆ (ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด: Python, Perl, Pascal ๋ฐ Lisp, Fortran, Erlang ๊ฐ๊ฐ).

์ข…์ด์— ์˜์‚ฌ ๊ตฌ์„ฑ์„ ๊ทธ๋ฆฐ ํ›„ ์ฃผ์˜ ๊นŠ๊ฒŒ ๋ถ„์„ํ•˜๊ณ  ๋ชจ๋“  ๊ฒƒ์ด ์ •์ƒ์ด๋ฉด ์œ ํšจํ•œ YAML ํŒŒ์ผ ํ˜•์‹์œผ๋กœ ํ˜•์‹์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

6. ํƒญ๊ณผ ๊ณต๋ฐฑ์˜ ๋”œ๋ ˆ๋งˆ

๋”œ๋ ˆ๋งˆ๋ฅผ ํ•ด๊ฒฐํ•ด์•ผ ํ•  ๊ฒƒ์ด๋‹ค. โ€œํƒญ์ด๋ƒ ๊ณต๋ฐฑ์ด๋ƒ?โ€. ๊ธ€๋กœ๋ฒŒํ•œ ์˜๋ฏธ๋Š” ์•„๋‹ˆ์ง€๋งŒ ์กฐ์ง ์ˆ˜์ค€์ด๋‚˜ ์ตœ์†Œํ•œ ํ”„๋กœ์ ํŠธ ์ˆ˜์ค€์—์„œ๋งŒ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—๋Š” sed ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•œ ํ›„์ฒ˜๋ฆฌ ์‚ฌ์šฉ, ํ”„๋กœ๊ทธ๋ž˜๋จธ ์ปดํ“จํ„ฐ์— ํ…์ŠคํŠธ ํŽธ์ง‘๊ธฐ ์„ค์ •, ํ•ด๊ณ  ์œ„ํ˜‘ ํ•˜์— linter์˜ ์ง€์นจ์„ ์—„๊ฒฉํ•˜๊ฒŒ ์ค€์ˆ˜ํ–ˆ๋‹ค๋Š” ์˜์ˆ˜์ฆ์„ ๋ณดํŽธ์ ์œผ๋กœ ๋ฐ›๋Š” ๊ฒƒ์ด ํฌํ•จ๋˜๋Š”์ง€ ์—ฌ๋ถ€๋Š” ์ค‘์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ๋“  YAML๊ณผ ๊ด€๋ จ๋˜๋ฉด ๊ณต๋ฐฑ๋งŒ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(YAML ์‚ฌ์–‘์—์„œ ์š”๊ตฌํ•˜๋Š” ๋Œ€๋กœ).

์ผ๋ฐ˜ ํ…์ŠคํŠธ ํŽธ์ง‘๊ธฐ์—์„œ๋Š” ์ž๋™ ์ˆ˜์ • ํƒญ์„ ์ง€์ •๋œ ๊ณต๋ฐฑ ์ˆ˜๋กœ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ฃผ์š” ์ง€์ง€์ž๋“ค์˜ ๋ฐ˜๋ž€์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ํƒญ ๋‘๋ ค์›Œํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

YAML์„ ์‹ซ์–ดํ•˜๋Š” ์‚ฌ๋žŒ์ด๋ผ๋ฉด ๋ˆ„๊ตฌ๋‚˜ ์ž˜ ์•Œ๊ณ  ์žˆ๋“ฏ์ด ํ™”๋ฉด์—์„œ๋Š” ํƒญ๊ณผ ๊ณต๋ฐฑ์˜ ์ฐจ์ด๋ฅผ ๋ณผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ˆˆ์— ๋ณด์ด์ง€ ์•Š๋Š” ๊ฒƒ์ด ์žˆ์„ ๋•Œ, ์‚ฌ๋žŒ๋“ค์€ ๋‹ค๋ฅธ ๋ชจ๋“  ๊ฐ€๋Šฅํ•œ ๋ฌธ์ œ๋ฅผ ๋ถ„๋ฅ˜ํ•˜๊ณ  ํ™•์ธํ•˜๊ณ  ์ œ๊ฑฐํ•œ ํ›„ ์ผ๋ฐ˜์ ์œผ๋กœ ๋งˆ์ง€๋ง‰์œผ๋กœ ๊ธฐ์–ตํ•ฉ๋‹ˆ๋‹ค. ๋„ํ‘œ ๊ณก์„ ์ด๋‚˜ ๊ณต๊ฐ„ ๋ธ”๋ก์„ ๊ฒ€์ƒ‰ํ•˜๋Š” ๋ฐ ํ•œ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฌ๋ฉด ๋‘˜ ์ค‘ ํ•˜๋‚˜๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ์ •์ฑ…์„ ๊ธด๊ธ‰ํ•˜๊ฒŒ ๋งŒ๋“  ๋‹ค์Œ ์ด๋ฅผ ์ค€์ˆ˜ํ•˜๋Š”์ง€ ์ฒ ๊ทผ ์ฝ˜ํฌ๋ฆฌํŠธ ์ ๊ฒ€์„ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค๋Š” ์‚ฌ์‹ค์ด ๋น„๋ช…์„ ์ง€๋ฅด๊ฒŒ ๋ฉ๋‹ˆ๋‹ค(์˜ˆ: ๋ฆฐํ„ฐ๋ฅผ ๊ฐ•์ œ๋กœ ํ†ต๊ณผ์‹œํ‚ค๊ธฐ ์œ„ํ•œ Git ํ›„ํฌ).

7. ์ ์„์ˆ˜๋ก ์ข‹๋‹ค(๋˜๋Š” ๋งŽ์„์ˆ˜๋ก ์ ๋‹ค)

์–ด๋–ค ์‚ฌ๋žŒ๋“ค์€ ๊ตฌ์กฐ๋ฅผ ๊ฐ•์กฐํ•˜๊ธฐ ๋•Œ๋ฌธ์— YAML๋กœ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์„ ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค. ๋™์‹œ์— ๋“ค์—ฌ์“ฐ๊ธฐ๋ฅผ ์ ๊ทน์ ์œผ๋กœ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ ๋ธ”๋ก์„ ๊ฐ•์กฐํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋ช…์‹œ์ ์ธ ๊ตฌ๋ถ„์ž๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋งˆํฌ์—… ์–ธ์–ด๋ฅผ ๋ชจ๋ฐฉํ•˜๋ ค๋Š” ์ผ์ข…์˜ ์‚ฌ๊ธฐ์ž…๋‹ˆ๋‹ค.

๋‹ค์Œ์€ ๊ทธ๋Ÿฌํ•œ ๊ตฌ์กฐ์˜ ์˜ˆ์ž…๋‹ˆ๋‹ค. ์•ค์„œ๋ธ” ๋ฌธ์„œ:

# Employee records
-  martin:
        name: Martin D'vloper
        job: Developer
        skills:
            - python
            - perl
            - pascal
-  tabitha:
        name: Tabitha Bitumen
        job: Developer
        skills:
            - lisp
            - fortran
            - erlang

์–ด๋–ค ์‚ฌ๋žŒ๋“ค์—๊ฒŒ๋Š” ์ด ์˜ต์…˜์ด ๋จธ๋ฆฌ ์†์˜ YAML ๊ตฌ์กฐ๋ฅผ ์ •๋ฆฌํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜์ง€๋งŒ, ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์—๊ฒŒ๋Š” ๋ถˆํ•„์š”ํ•œ ๋“ค์—ฌ์“ฐ๊ธฐ๋กœ ์ธํ•ด ์งœ์ฆ์ด ๋‚œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ๊ท€ํ•˜๊ฐ€ YAML ๋ฌธ์„œ์˜ ์†Œ์œ ์ž์ด๊ณ  ์ด๋ฅผ ์œ ์ง€ ๊ด€๋ฆฌํ•  ์ฑ…์ž„์ด ์žˆ๋Š” ๊ฒฝ์šฐ ๋„ˆ์™€ ๋„ˆ๋ฟ์ด์•ผ ๋“ค์—ฌ์“ฐ๊ธฐ ์‚ฌ์šฉ ๋ฐฉ๋ฒ•์„ ์ •์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํฐ ํŒจ๋”ฉ์ด ์งœ์ฆ๋‚˜๋Š” ๊ฒฝ์šฐ YAML ์‚ฌ์–‘์— ๋”ฐ๋ผ ๊ฐ€๋Šฅํ•œ ํ•œ ์ตœ์†Œํ•œ์œผ๋กœ ์œ ์ง€ํ•˜์„ธ์š”. ์˜ˆ๋ฅผ ๋“ค์–ด, Ansible ๋ฌธ์„œ์˜ ์œ„ ํŒŒ์ผ์€ ์†์‹ค ์—†์ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋‹ค์‹œ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

---
- martin:
   name: Martin D'vloper
   job: Developer
   skills:
   - python
   - perl
   - pascal
- tabitha:
   name: Tabitha Bitumen
   job: Developer
   skills:
   - lisp
   - fortran
   - erlang

8. ๊ณต๋ฐฑ์„ ์‚ฌ์šฉํ•˜์„ธ์š”

YAML ํŒŒ์ผ์„ ์ž‘์„ฑํ•  ๋•Œ ๋™์ผํ•œ ์‹ค์ˆ˜๋ฅผ ๊ณ„์† ๋ฐ˜๋ณตํ•œ๋‹ค๋ฉด ํ…œํ”Œ๋ฆฟ์„ ์ฃผ์„์œผ๋กœ ์‚ฝ์ž…ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๋‹ค์Œ ๋ฒˆ์—๋Š” ์ด ํ…œํ”Œ๋ฆฟ์„ ๋ณต์‚ฌํ•˜์—ฌ ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฅผ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

---
# - <common name>:
#   name: Given Surname
#   job: JOB
#   skills:
#   - LANG
- martin:
  name: Martin D'vloper
  job: Developer
  skills:
  - python
  - perl
  - pascal
- tabitha:
  name: Tabitha Bitumen
  job: Developer
  skills:
  - lisp
  - fortran
  - erlang

9. ๋ญ”๊ฐ€ ๋‹ค๋ฅธ ๊ฒƒ์„ ์‚ฌ์šฉํ•˜๋ผ

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‚ฌ์šฉ์ž๋ฅผ ๋ฐฉํ•ดํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด YAML์„ ๋‹ค๋ฅธ ํ˜•์‹์œผ๋กœ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ์‹œ๊ฐ„์ด ์ง€๋‚จ์— ๋”ฐ๋ผ ๊ตฌ์„ฑ ํŒŒ์ผ์ด ์ž์ฒด์ ์œผ๋กœ ์ปค์งˆ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ Lua ๋˜๋Š” Python์˜ ๊ฐ„๋‹จํ•œ ์Šคํฌ๋ฆฝํŠธ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

YAML์€ ๋ฏธ๋‹ˆ๋ฉ€๋ฆฌ์ฆ˜๊ณผ ๋‹จ์ˆœ์„ฑ์œผ๋กœ ์ธํ•ด ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ์ข‹์•„ํ•˜๋Š” ํ›Œ๋ฅญํ•œ ๋„๊ตฌ์ด์ง€๋งŒ ๋ฌด๊ธฐ๊ณ ์˜ ์œ ์ผํ•œ ๋„๊ตฌ๋Š” ์•„๋‹™๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋•Œ๋กœ๋Š” ๊ฑฐ์ ˆํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. YAML์— ๋Œ€ํ•œ ๊ตฌ๋ฌธ ๋ถ„์„ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์‰ฝ๊ฒŒ ์ฐพ์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์†์‰ฌ์šด ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์˜ต์…˜์„ ์ œ๊ณตํ•˜๋ฉด ์‚ฌ์šฉ์ž๋Š” ๋น„๊ต์  ์–ด๋ ค์›€ ์—†์ด ์ด๋Ÿฌํ•œ ์‹คํŒจ๋ฅผ ๊ทน๋ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

YAML ์—†์ด๋Š” ํ•  ์ˆ˜ ์—†๋‹ค๋ฉด ๋‹ค์Œ 10๊ฐ€์ง€ ํŒ์„ ํ™œ์šฉํ•˜์—ฌ YAML์— ๋Œ€ํ•œ ํ˜์˜ค๊ฐ์„ ์™„์ „ํžˆ ๊ทน๋ณตํ•˜์„ธ์š”!

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€