yaml 파일을 읽고 수정할때 유용한 yq 알아보기
자동화 설정을 하거나 bash 스크립트를 구성할 때 yml 파일의 값을 읽고 다른 값으로 변경해야 할 경우가 있다. 이때 유용한 yq 에 대한 글이다.
yq v4 버전으로 작성된 글이며, 이전 버전인 v3 와 달라진 점은 아래 공식문서 링크를 참고하면 좋을 것 같다.
https://mikefarah.gitbook.io/yq/upgrading-from-v3#updating-writing-documents
yq 알아보기
jq 가 JSON 을 다뤘다면, YAML 파일을 읽고 수정할 수 있는 명령어 기반 도구가 yq 다. 기존에 YAML 파일을 처리하려면 sed나 awk처럼 구조를 모르는 텍스트 도구를 사용해야 했지만, 이는 실수가 발생하기 쉽고 유지보수가 어렵다. yq는 YAML 구조를 인식한 채 탐색하고 수정할 수 있어 훨씬 안전하고 선언적인 방식으로 YAML을 다룰 수 있다.
yq 명령어 기본 사용법
기본적인 조회 명령어는 다음과 같다.
yq '.metadata.name' config.yaml
config.yaml에서 metadata.name 항목의 값을 출력한다.
파일 내 값을 직접 수정하려면 -i 옵션을 사용한다.
yq -i '.metadata.name = "new-name"' config.yaml
config.yaml 파일 내 metadata.name 값을 "new-name"으로 변경한다.
리스트 안의 특정 요소를 바꾸려면 index 또는 조건을 사용한다.
# 인덱스 이용
yq -i '.items[0].enabled = true' config.yaml
# select 로 조건 지정
yq -i '(.services[] | select(.name == "backend").enabled) = true' config.yaml
값을 추가할 때는 += 연산자를 사용할 수 있다.
yq -i '.services += {"name": "new-service", "enabled": true}' config.yaml
값을 삭제할 때는 del() 함수를 사용한다.
yq -i 'del(.services[0])' config.yaml
사용 예시
모니터링 서버에서 s3 에 올라가 있는 프로메테우스 설정을 받아서 targets 의 ip 를 할당해 줘야 한다고 가정한다.
# prometheus.yml
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['prometheus:9090']
- job_name: 'springboot'
metrics_path: '/actuator/prometheus'
relabel_configs:
- source_labels: [__address__]
target_label: application
replacement: baroit-backend
static_configs:
- targets: ['host.docker.internal:8080']
labels:
application: baroit-backend
위 prometheus.yaml 에서 targets 를 바꿔보자.
yq -i '(.scrape_configs[] | select(.job_name == "springboot").static_configs[].targets) = ["10.0.3.42:8080"]' prometheus.yml
targets 값이 지정한 값으로 바뀐 것을 확인할 수 있다.
.env 파일 값 export 후 할당해 변경하기
예시로 .env 를 사용하고 아래처럼 구성되어 있을 때 이 값을 넣어보자.
.env 값을 export 해주고
set -o allexport ✔ │ base │ 09:46:33 PM
source .env
set +o allexport
그 후 yq 명령어에서 shell 변수를 삽입한다.
yq -i '(.scrape_configs[] | select(.job_name == "springboot").static_configs[].targets) = ["'"$BACKEND_IP:$PROMETHEUS_PORT"'"]' prometheus.yml
위 변수 치환 방법은 아래와 같이 동작한다.
- 외부 '로 문자열을 닫아 bash가 해석을 잠시 멈춘다
- 내부 " 안에서 $BACKEND_IP:$PROMETHEUS_PORT 가 실제 값으로 확장된다
- 다시 '로 감싸서 최종적으로 확장된 값을 작은따옴표로 감싸는 문자열을 만든다
인자값을 넘길 때 자주 사용되므로 기억하면 좋을 것 같다.