Dev

Jsonnet 소개

April 18, 2018

Jsonnet 소개

Jsonnet은 JSON에 몇 가지 기능을 확장한 템플릿 언어입니다.

설정을 저장하기 위한 파일 형식으로 가장 넓게 사용되는 것은 JSON, YAML이 있습니다.
대부분의 경우 이 두 가지 중 하나로 충분하지만, 가끔 이것만으로는 불충분한 경우가 있습니다.
구체적인 예시를 들자면 이렇습니다.

  • 기본 설정이 존재하고 이를 확장해서 여러 환경 간에 설정을 돌려쓰고 싶을 때
  • 외부로부터 설정 값을 주입받을 필요가 있을 때

JSON, YAML에서 이러한 요구를 감당하기 위해서는 중간 언어(erb 등의 템플릿 언어)를
도입할 필요(또는 그냥 전부 복붙)가 있었는데요. Jsonnet을 이용하면 그럴 필요 없이
그 자체만으로 깔끔하게 관리할 수 있습니다.

JSON과 다른 점

Jsonnet의 홈페이지에서는 A data templating language for app and tool developers라고
언어를 소개하고 있습니다. 이를 위해, JSON에서 변수 선언, 조건분기, 수치연산,
함수 정의&호출, import, 에러 전파 등의 기능을 확장하고 있습니다.
위에서 들었던 예시를 보죠.

Case

자세한 문법은 Jsonnet를 참조하세요.

설정을 돌려쓰고 싶을 때

// staging
{ 
  api: {
    timeout: 10,
  }
}

// production
{
  api: {
    timeout: 10,
  }
  rack_timeout: 10
}

위와 같은 설정이 있다고 합시다. 거의 동일하지만 환경에 따라 추가 설정이 있습니다.
Jsonnet으로는 아래와 같이 작성할 수 있습니다.

// base.libsonnet
{
  api: {
    timeout: 10,
  }
}

// staging.jsonnet
import 'base.libsonnet'

// production.jsonnet
(import 'base.libsonnet') + {
  rack_timeout: 10
}
  • import 구문을 통해 다른 파일을 읽어올 수 있습니다.
  • 읽어온 데이터를 + 를 사용해 손쉽게 확장할 수 있습니다.

예제 상에서는 설정 항목이 적어서 이점이 눈에 잘 보이지 않을 수 있지만,
항목 수가 늘어날수록 감사함을 느낄 수 있게 됩니다.

외부로부터 설정 값을 주입받을 필요가 있을 때

Rails에서 가장 흔하게 볼 수 있는 secret.yml을 예제로 들어보죠.
이 파일은 확장자가 yml 이지만, erb 컴파일을 거쳐서 사용되는 파일이라는 건 다들 아실거라 생각하고…

secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>

이는 Jsonnet 으로 작성하면 다음과 같이 작성할 수 있습니다.
(memo: 알기 쉬운 예시로 들었을 뿐이지, Rails가 직접 관리하므로 패치를 끼우지 않으면 이런 방식으로 사용할 수 없습니다)

{
  secret_key_base: std.extVar("SECRET_KEY_BASE")
}

std.extVar를 이용해서 컴파일 시에 --ext-str <var>=<val> 형식으로 넘겨준 값을 사용할 수 있습니다.

실제 사례

일반적인 애플리케이션에서는 확장 기능을 통해서 얻을 수 있는 이점이 상대적으로 적지만,
설정 파일의 내용물 중복이 쉽게 발생하며, (비밀키 등의 주입을 위해) 외부에서 값을
참조해야 하는 설정 관리용 레포지토리에서는 이러한 기능이 커다란 장점이 됩니다.

구체적으로 예를 들자면 컨테이너를 배포하기 위해 사용하는
hako에서는 각 애플리케이션의 설정 파일로서
YAML 뿐만 아니라 Jsonnet도 지원하고 있습니다.
사내에서는 ECS 를 이용한 애플리케이션의 hako 설정 파일을 한 저장소에서 관리하고 있는데요,
이러한 경우에 굉장히 유용하게 사용됩니다.

결론

  • (여러 파일이든 한 파일이든)설정 내에서 (미묘하게) 중복되는 내용이 다수 있다.
  • 외부에서 값을 넘겨 받아야 하거나, 문자열 연결 등의 연산이 필요하다.

위와 같은 경우에는 대안으로 Jsonnet을 이용해보는 것도 나쁘지 않을까 싶습니다.