YAML은 구성 파일을 작성할 때 자주 사용하는 데이터 직렬화 언어입니다. 이는 이해하기 쉽고 사람이 읽을 수 있으며, 여러 프로그래밍 언어와 함께 사용할 수 있어 인기 있는데요. 특히 YAML은 DevOps 도구의 스크립팅과 자동화 프로세스 정의, CI/CD 파이프라인 구성 작업에서 중요하게 쓰입니다. 이는 오늘날 DevOps에서 핵심 역할을 수행하고요. 소프트웨어 개발 라이프라이클 전반에 걸쳐 DevOps를 올바르게 구현하려면 YAML을 제대로 이해해야 하죠. 오늘은 YAML 특징과 구문, 활용 사례를 알아보고요. DevOps 핵심 워크플로인 CI/CD 파이프라인에서 YAML 의의를 살펴보겠습니다.
1. YAML 소개
1.1 탄생 배경
YAML은 사람이 읽을 수 있고 컴퓨팅 측면에서 강력한 데이터 직렬화 언어를 만드는 국제적 협업입니다. YAML을 만든 사람은 Ingy döt Net, Clark Evans, Oren Ben-Kiki인데요. YAML은 두 가지 노력이 결합한 결과물이라고 하죠. Ingy döt Net은 Inline을 위한 직렬화 형식이 필요했는데요. 이는 ‘Data::Denter 모듈’이라는 결과물로 나타났습니다. 한편, Oren Ben-Kiki, Clark Evans는 sml-dev 그룹에서 XML을 간소화하고자 협업했고요.
YAML은 2001년 5월 12일 처음 공개됐는데요. Oren과 Clark의 YAML 비전이 Ingy의 Data::Denter와 비슷했다고 합니다. 며칠 뒤, 그들은 팀을 이뤘고 YAML이 탄생했죠. YAML 이름은 "Yet Another Markup Language(또 다른 마크업 언어)"의 약어인데요. "YAML Ain't Markup Language(YAML은 마크업 언어가 아니다)"라는 의미도 있습니다. 이는 YAML이 단순 마크업 언어가 아닌 ‘데이터 중심의 언어임’을 강조하죠.
1.2 주요 특징
YAML은 가독성, 언어 지원, 재사용성, 유연성 측면에서 다음 특징이 있습니다.
- 가독성: YAML은 깔끔하고 읽기 쉬운 형식을 제공합니다. 들여쓰기를 사용해 데이터 구조를 시각적으로 나타내고요. 필요에 따라 간결하게 작성하거나 자세히 표현할 수 있습니다.
- 언어 지원 다양성: YAML은 Perl, Python, Ruby, Java, JavaScript, C# 등 여러 프로그래밍 언어와 호환됩니다. 다양한 언어로 작성한 프로그램에서 YAML 형식을 편리하게 사용할 수 있습니다.
- 재사용성: YAML은 복잡한 데이터 구조를 쉽게 재사용하도록 지원합니다. 예를 들어, 하나의 YAML 파일에 정의한 객체를 다른 부분에 참조해 사용할 수 있습니다.
- 유연성: YAML은 단순한 구성부터 복잡한 스크립트까지 다양한 수준으로 데이터를 표현합니다. 이는 여러 소프트웨어 개발 과정에서 유연하게 사용할 수 있습니다.
2. YAML 구문과 예제
2.1 구문
YAML 구문에는 대표적으로 다음 요소가 있습니다.
- 시퀀스(Sequence): 언어의 배열이나 목록 같은 순차적 요소 모음입니다. 목록 시퀀스는 대시(-)로 시작합니다. 시퀀스의 모든 항목은 같은 간격으로 들여쓰기합니다.
- 매핑(Mapping): 각 키가 값과 연결된 키-값 쌍의 집합입니다. 이는 객체나 해시 테이블을 표현합니다. 키와 값을 콜론(
:
)으로 구분하며, 들여쓰기로 구조를 표현합니다. - 스칼라(Scalar): 문자열, 정수, 날짜, 숫자, 부울 등 값으로 사용할 수 있는 임의의 데이터입니다.
- 주석:
#
기호로 표시됩니다. 주석은 YAML 파일에 설명, 컨텍스트를 더하며 코드를 이해하는 데 쓰입니다.
2.2 예제
아래는 위 요소를 담은 YAML 구문 예제입니다.
yamlCopy code
# Employee records
- name: John Doe
job: Developer
skills:
- Python
- JavaScript
- SQL
- name: Jane Smith
job: Designer
skills:
- Adobe Photoshop
- Sketch
- Illustrator
# Database configuration
database:
host: localhost
port: 5432
username: admin
password: admin123
이 예제는 직원 기록(# Employee records
)과 데이터베이스 설정(# Database configuration
)을 나타 냈습니다.
먼저 직원 기록에서는 직원 목록을 시퀀스 형태(예: - name: John Doe
, - name: Jane Smith
)로 표현했습니다. 각 직원의 이름, 직업, 기술은 매핑 형태(예: name: John Doe
, job: Developer
, skills: Python
)로 나타냈습니다.
한편, 데이터베이스 설정에서도 호스트, 포트, 사용자 이름, 비밀번호를 매핑 형태(예: host: localhost
, port: 5432
, username: admin
, password: admin123
)로 표현했습니다.
3. YAML 활용 사례
3.1 구성 파일 작성
YAML은 구성 파일을 작성하는 데 자주 쓰입니다. 특히 이는 웹 서버 설정, 데이터베이스 연결 정보, 애플리케이션 환경 설정 등을 기술할 때 사용하죠. YAML은 구조화되고, 읽기 쉬운 형식이라서 구성 파일에 잘 맞습니다.
- 예제: Docker Compose에서는 애플리케이션 서비스를 구성할 때 YAML 파일을 사용합니다. 이 예제는 Docker Compose에서 요청받는 web과 요청 횟수를 기록하는 카운터 역할을 하는 redis 서비스를 작성합니다.
version: "3.9" # optional since v1.27.0
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- README.md:/docs/README.md
- logvolume01:/var/log
networks:
- service-network
redis:
image: redis
networks:
- service-network
volumes:
logvolume01: {}
networks:
service-network: {}
3.2 스크립팅·자동화 프로세스 정의
YAML은 DevOps 도구에서 스크립팅을 수행하고, 자동화 프로세스를 정의할 때 활용됩니다. 이는 복잡한 명령과 작업을 단순화하고, 오류를 줄이며, 재사용하기 쉽게 합니다.
- 예제: Ansible에서는 YAML 파일인 ‘Playbook’으로 작업과 자동화 프로세스를 정의합니다. YAML 템플릿으로 반복 작업을 자동으로 프로그래밍할 수 있습니다. 이 예제에서는 Ansible Playbook을 실행하기 위해 첫 번째 play는 웹 서버를 대상으로, 두 번째 play는 DB 서버를 대상으로 정의합니다.
---
- name: Update web servers
hosts: webservers
remote_user: root
tasks:
- name: Ensure apache is at the latest version
ansible.builtin.yum:
name: httpd
state: latest
- name: Write the apache config file
ansible.builtin.template:
src: /srv/httpd.j2
dest: /etc/httpd.conf
- name: Update db servers
hosts: databases
remote_user: root
tasks:
- name: Ensure postgresql is at the latest version
ansible.builtin.yum:
name: postgresql
state: latest
- name: Ensure that postgresql is started
ansible.builtin.service:
name: postgresql
state: started
3.3 CI/CD 파이프라인 구성
YAML은 CI/CD 파이프라인을 구성할 때, 핵심 역할을 수행합니다. 이는 파이프라인 단계와 대상을 정의하는 데 사용됩니다. 이로써 프로젝트 빌드, 테스트, 배포 과정을 자동화합니다.
- 예제: GitLab에서 CI/CD 파이프라인을 정의할 때 YAML 파일을 사용합니다. 이 예제에서는 파이프라인을 구성하기 위해 아래 내용에 따라
.gitlab-ci.yml
파일을 생성합니다. 이어서semantic-release
를 실행하는 단일 jobpublish
로 파이프라인을 구성합니다.
default:
image: node:latest
before_script:
- npm ci --cache .npm --prefer-offline
- |
{
echo "@${CI_PROJECT_ROOT_NAMESPACE}:registry=${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/npm/"
echo "${CI_API_V4_URL#https?}/projects/${CI_PROJECT_ID}/packages/npm/:_authToken=\${CI_JOB_TOKEN}"
} | tee -a .npmrc
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- .npm/
workflow:
rules:
- if: $CI_COMMIT_BRANCH
variables:
NPM_TOKEN: ${CI_JOB_TOKEN}
stages:
- release
publish:
stage: release
script:
- npm run semantic-release
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
3.4 클라우드 오케스트레이션
YAML은 클라우드 리소스, 서비스를 관리하는 오케스트레이션에서 필수입니다. 특히 이는 클라우드 인프라를 코드로 정의할 때 사용됩니다.
- 예제: YAML 파일은 pod, 오브젝트, 배포 등 Kubernetes 리소스를 생성합니다. Kubernetes 디플로이먼트 오브젝트를 생성해 애플리케이션을 실행하고, 디플로이먼트 명세를 YAML 파일에 기술할 수 있습니다. 이 예제는 Kubernetes에서 YAML을 사용해 nginx:1.14.2 Docker 이미지를 실행하는 디플로이먼트 명세를 정의합니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2 # tells deployment to run 2 pods matching the template
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
3.5 데이터 직렬화·교환
YAML은 사람이 읽을 수 있을 정도로 가독성이 높아서 데이터를 직렬화하고 애플리케이션 간 데이터를 교환하는 데 쓰입니다. 이를 사용하면 들여쓰기와 키-값 쌍, 댜앙한 문자와 기호로 데이터 구조를 자연어와 비슷하게 표현할 수 있습니다. YAML은 JSON과 XML의 대안으로 꼽힙니다. 이는 ‘JSON보다 가독성이 좋고, 복잡한 데이터 구조 지원 측면에서 우수하다’고 평가받습니다. 또 ‘XML보다 간결하고, 단순하다’고 인정받습니다.
- 예제: 이 예제는 API 설정과 데이터 교환을 위해 YAML 형식으로 데이터 구조를 직관적으로 나타냅니다.
# API configuration
apiVersion: v1
kind: APIResource
metadata:
name: my-api
spec:
endpoint: /api/data
method: GET
authorization:
type: OAuth2
timeoutSeconds: 30
이 밖에도 YAML은 다양한 용도로 활용됩니다. 이는 유연하고, 사용자 친화적이라서 기술 분야에서 널리 확장되고 있죠. 특히 YAML 파일은 CI/CD 파이프라인 구성에서 거의 표준으로 사용하는데요. Jenkins처럼 GUI(그래픽 사용자 인터페이스)로 설정하는 것보다(물론 jenkinsfile로도 설정 가능) 장점이 크죠. 이에 많은 개발 프로젝트에서 YAML로 빌드/배포 환경을 구축하고 있습니다.