데이터 형식 · 2026년 8월 28일

YAML 앵커와 별칭 설명 (복붙 예제 포함)

YAML 앵커(&)와 별칭(*)는 복붙 없이 설정을 재사용할 수 있게 합니다. 작동 방식, 사용 시기, 그리고 프로덕션에서 사람들을 당기는 엣지 케이스.

설정 파일에서 동일한 10줄의 YAML을 세 곳에 복붙한 적이 있다면, YAML 앵커가 해결하도록 설계된 고통을 느꼈을 것이다. 앵커는 값을 한 번 정의하고 동일한 문서의 어디에서든 참조할 수 있게 해준다. 한 곳에서 값을 변경하면 모든 참조가 업데이트된다.

이 글은 앵커와 별칭이 어떻게 작동하는지, 언제 사용하는지, 그리고 사람들을 당기는 엣지 케이스를 설명한다.

기본 문법

YAML 앵커는 노드에 부여하는 이름이다:

defaults: &defaults
  retries: 3
  timeout: 30
  log_level: info

&defaults가 앵커이다. 이것은 defaults의 값에 부착되고, 이것은 맵이다. 문자열, 숫자, 목록, 맵, 시퀀스 등 어떤 노드에도 앵커를 둘 수 있다.

별칭은 앵커에 대한 참조이다:

production:
  <<: *defaults
  region: us-east-1
  replicas: 5

staging:
  <<: *defaults
  region: us-west-2
  replicas: 2

<<: *defaults는 “병합 키”이다. “defaults라는 앵커에서 모든 것을 가져와 이 맵에 병합하라”고 말한다. 결과는 defaults 내용을 인라인으로 작성한 것과 같다:

production:
  retries: 3
  timeout: 30
  log_level: info
  region: us-east-1
  replicas: 5

하지만 defaults에서 retries를 변경하면, 앵커를 사용하는 모든 곳이 업데이트된다. 그것이 요점이다.

단일 값에 대한 앵커

앵커가 맵에 병합될 필요는 없다. 단일 값을 앵커하고 참조할 수 있다:

api_version: &api "v2.1.0"
services:
  auth:
    version: *api
  billing:
    version: *api
  reports:
    version: *api

이제 API 버전을 변경하는 것은 한 줄 변경이다. 참조가 모두 따라온다.

목록도 앵커할 수 있다:

allowed_origins: &origins
  - https://app.example.com
  - https://admin.example.com
  - https://staging.example.com

cors:
  web: *origins
  api: *origins

목록이 그대로 재사용된다.

앵커가 도움이 되는 경우

앵커는 여러 인스턴스에 걸쳐 공유된 기본값이 있을 때 빛난다. Kubernetes 매니페스트, docker-compose 파일, CI 매트릭스는 이 패턴으로 가득하다.

2026년 참고: Helm과 Kustomize가 이제 Kubernetes 템플릿을 지배하고 있고, 이것은 YAML 앵커 시스템 바깥에서 작동한다 — YAML을 생성하고, 파싱하지 않는다. Helm이나 Kustomize를 사용하는 경우 앵커가 필요 없다(대신 values.yaml과 패치 오버레이가 있다). 앵커는 여전히 순수 kubectl apply -f 워크플로, GitHub Actions 매트릭스, docker-compose 파일, 템플릿 엔진을 거치지 않는 수동 작성 설정에 대한 올바른 선택이다.

Kubernetes 예제 — 같은 리소스 제한을 가진 세 서비스:

base_resources: &base_resources
  requests:
    cpu: 100m
    memory: 128Mi
  limits:
    cpu: 500m
    memory: 512Mi

apiDeployment:
  spec:
    template:
      spec:
        containers:
          - name: api
            image: myapp/api:1.2.3
            resources: *base_resources

workerDeployment:
  spec:
    template:
      spec:
        containers:
          - name: worker
            image: myapp/worker:1.2.3
            resources: *base_resources

docker-compose 예제 — 개발과 프로덕션의 같은 환경:

common_env: &common_env
  DATABASE_URL: postgres://db.internal/app
  REDIS_URL: redis://cache.internal:6379
  LOG_LEVEL: info

services:
  api:
    environment:
      <<: *common_env
      ENVIRONMENT: dev
  worker:
    environment:
      <<: *common_env
      ENVIRONMENT: dev

둘 다에서 공유 환경을 변경하는 것은 한 줄 편집이다.

Gotcha

앵커는 강력하지만 몇 가지 날카로운 면이 있다.

앵커는 문서에 로컬이다. (--- 구분자가 있는) 다중 문서 YAML 파일은 앵커에 대해 자체 범위를 가진다. 문서 하나에 정의된 앵커는 문서 둘에서 참조할 수 없다. 다중 문서 YAML을 생성하는 도구를 사용하는 경우(예: 여러 리소스가 있는 kubectl get -o yaml), 앵커를 사용하여 값을 공유할 수 없다.

앵커와 병합은 놀라운 방식으로 재정의와 상호작용한다. 앵커와 참조 맵이 같은 키를 정의하면, 참조 맵의 값이 이긴다:

defaults: &defaults
  retries: 3
  timeout: 30

production:
  <<: *defaults
  retries: 10  # 이것이 이긴다

그래서 production.retries는 3이 아니라 10이다. 이것은 예상된 동작이지만, 순서에 따라 “마지막이 이긴다” 또는 “첫 번째가 이긴다”를 기대하는 사람들에게 타격을 준다.

병합된 맵의 키는 제거할 수 없다. defaults에 legacy_setting: true 키가 있고 production에서 “설정 해제”하고 싶으면 불가능하다. 병합은 키를 추가만 하고, 절대 제거하지 않는다. 해결 방법: 앵커에 키를 포함하지 않는 것이다.

앵커는 자기 자신을 참조할 수 없다. 자기 참조 앵커는 순환을 만든다. 대부분의 파서는 이를 감지하고 오류를 던진다. “재귀적 앵커” 오류가 발생하면, 포함하는 앵커를 가리키는 별칭을 찾아라.

앵커와 JSON은 섞이지 않는다. JSON에는 앵커 개념이 없다. 앵커가 있는 YAML을 JSON으로 변환하면, 앵커가 확장된다(JSON이 커지거나) 또는 삭제된다(JSON이 작아지거나). 어느 쪽이든 결과는 YAML보다 크다. JSON 버전이 필요하면, 보통 다른 설정 소스가 필요하다.

일부 린터가 앵커에 대해 불평한다. yamllint는 스타일상의 이유로 앵커를 비활성화하는 것이 기본값이다(anchors: disable). 앵커를 사용하는 경우, 린터를 구성하거나 경고를 수락해야 한다. 앵커를 사용하는 대부분의 팀은 린트 마찰에 가치가 있다고 생각한다.

앵커는 파싱된 객체 그래프에서 작동하고, 텍스트에서 작동하지 않는다. yq와 같은 도구로 키를 알파벳순으로 정렬한 다음 다시 직렬화하면, 앵커는 보이는 키 순서가 아니라 참조로 보존된다. 출력은 여전히 올바르지만, 시각적으로 놀랄 수 있다 — 앵커가 한 곳에 나타나고, 별칭이 다른 곳에 나타나고, 둘 다 같은 객체를 가리킨다.

설정에서 앵커 확인

앵커가 작동하는지 확인하는 가장 빠른 방법은 앵커를 해석하는 파서에서 YAML을 로드하고 결과를 출력하는 것이다. DevSpeedTools의 YAML 검증기는 해석된 객체 그래프를 보여준다 — 앵커가 올바르게 연결되어 있으면, 어디서든 같은 값을 볼 수 있다.

더 정밀한 검사를 위해, YAML 통계 도구는 고유 vs. 중복된 키의 총 수를 알려주고, 이것은 “앵커가 실제로 무언가를 중복 제거하고 있는가?“에 대한 좋은 지표이다.

대화형 편집 경험의 경우, Red Hat YAML 확장이 있는 VS Code는 호버 시 앵커를 해석하고 각 별칭이 어디를 가리키는지 보여준다.

요약

앵커는 YAML의 변수 버전이다. 파싱 시에 작동하고, 직렬화 시가 아니라, 작성하는 파일에 앵커가 한 번, 참조가 여러 곳에 들어간다. 파서는 같은 값으로 확장한다.

공유 기본값에 사용하라. 문서 간 상태를 공유하려고 사용하지 마라. JSON 변환에서 보존되기를 기대하지 마라. 그리고 의심이 나면, 검증기를 통해 파일을 실행하여 확장이 의도와 일치하는지 확인하라 — 조용히 잘못된 값을 생성하는 앵커는 프로덕션에 출시되어 1년간 머무는 종류의 버그이다.