HCL 입력 변수 참조

HCL 입력 변수 참조

입력 변수(input variables)는 Nomad job의 매개변수 역할을 해서, job 자체의 소스 코드를 바꾸지 않고도 job의 여러 측면을 사용자 정의할 수 있게 해줘요.

출처: 문서

본문

입력 변수는 Nomad job의 매개변수 역할을 하며, job의 여러 측면을 job 자체의 소스 코드를 바꾸지 않고 사용자 정의할 수 있게 해줘요.

job 사양과 같은 파일에 변수를 선언하면 CLI 옵션과 환경 변수로 그 값들을 설정할 수 있어요.

참고: 간결함을 위해 입력 변수를 문맥상 어떤 변수를 말하는지 명확할 때 "변수(variables)"라고 줄여 부르기도 해요(HCL job 파일과 관련된). 이들은 런타임 시 job에서 접근할 수 있는 소량의 구성이나 비밀 데이터를 저장하는 데 유용한 Nomad Variables와 혼동하면 안 돼요. Nomad의 다른 변수 종류로는 (Nomad가 실행되는 셸이 설정하는) 환경 변수와 표현식에서 값을 간접적으로 나타내는 데 사용되는 표현식 변수가 있어요.

입력 변수 선언 (Declaring an Input Variable)

job이 받아들이는 각 입력 변수는 variable 블록을 사용해 선언해야 해요.

variable "image_id" {
  type = string
}

variable "availability_zone_names" {
  type    = list(string)
  default = ["us-west-1a"]
}

variable "docker_ports" {
  type = list(object({
    internal = number
    external = number
    protocol = string
  }))
  default = [
    {
      internal = 8300
      external = 8300
      protocol = "tcp"
    }
  ]
}

또는 덜 정밀한 variables 블록을 사용할 수도 있어요.

variables {
  foo       = "value"
  my_secret = "foo"
}

variable 키워드 뒤의 라벨 또는 variables 블록의 라벨은 변수의 이름이며, 같은 job의 모든 변수 중에서 고유해야 해요. 이 이름은 외부에서 변수에 값을 할당하고 job 안에서 변수 값을 참조하는 데 사용돼요.

variable 블록은 선택적으로 type 인자를 포함해 변수에 어떤 값 타입을 허용할지 지정할 수 있어요. 다음 절에서 설명할게요.

variable 선언은 default 인자도 포함할 수 있어요. default가 있으면 변수는 선택적(optional) 으로 간주되며, job을 호출하거나 Nomad를 실행할 때 값이 설정되지 않으면 기본 값이 사용돼요. default 인자는 리터럴 값을 요구하며 구성의 다른 객체를 참조할 수 없어요.

입력 변수 값 사용 (Using Input Variable Values)

변수를 선언한 job 안에서 그 값은 표현식에서 var.<NAME>로 접근할 수 있어요. <NAME>은 선언 블록에 주어진 라벨과 일치해요.

config {
  image = var.task_image
  label = var.task_labels
}

변수에 할당된 값은 변수가 선언된 폴더 안의 표현식에서만 접근할 수 있어요. 블록 라벨(예: job ID나 task group 이름)은 표현식이 아니므로 변수나 로컬로 보간할 수 없다는 점에 유의하세요.

타입 제약 (Type Constraints)

variable 블록의 type 인자를 사용하면 변수의 값으로 받아들여질 값 타입을 제한할 수 있어요. 타입 제약이 설정되지 않으면 어떤 타입의 값이든 받아들여져요.

타입 제약은 선택 사항이지만 지정하는 것을 권장해요. 이는 job 사용자에게 쉬운 알림 역할을 하고, 잘못된 타입이 사용되면 Nomad가 도움이 되는 오류 메시지를 반환하게 해주기 때문이에요.

타입 제약은 타입 키워드와 타입 생성자의 혼합으로 만들어져요. 지원되는 타입 키워드는 다음과 같아요.

타입 생성자는 컬렉션 같은 복잡한 타입을 지정할 수 있게 해줘요.

any 키워드는 어떤 타입이든 허용된다는 것을 나타내는 데 사용할 수 있어요. 이러한 다양한 타입의 의미와 동작, 그리고 복잡한 타입의 자동 변환에 대한 자세한 내용은 Type Constraints를 참고하세요.

type과 default 인자가 모두 지정되면 주어진 기본 값은 지정된 타입으로 변환 가능해야 해요.

default만 지정되면 기본 값의 타입이 사용돼요.

type과 default가 모두 지정되지 않고 환경 변수에서나 명령줄에서 변수를 설정하려 하면, 변수는 항상 문자열로 해석돼요.

입력 변수 문서화 (Input Variable Documentation)

job의 입력 변수는 사용자 인터페이스의 일부이므로, 선택적인 description 인자를 사용해 각 변수의 목적을 간단히 설명할 수 있어요.

variable "image_id" {
  type        = string
  description = "The docker image used for task."
}

설명은 변수의 목적과 어떤 종류의 값이 기대되는지 간결하게 설명해야 해요. 이 설명 문자열은 job에 대한 문서에 포함될 수 있으므로, job의 유지 관리자가 아니라 job의 사용자 관점에서 작성해야 해요. job 유지 관리자를 위한 주석은 주석(comments)을 사용하세요.

입력 변수 사용자 정의 검증 규칙 (Input Variable Custom Validation Rules)

입력 변수는 해당 variable 블록 안에 중첩된 validation 블록을 사용해 특정 변수에 대한 임의의 사용자 정의 검증 규칙을 지정하는 것을 지원해요.

variable "image_id" {
  type        = string
  description = "The id of the machine image (AMI) to use for the server."

  validation {
    condition     = substr(var.image_id, 0, 4) == "ami-"
    error_message = "The image_id value must be a valid AMI id, starting with \"ami-\"."
  }
}

condition 인자는 변수의 값을 사용해 값이 유효하면 true, 유효하지 않으면 false를 반환해야 하는 표현식이에요. 이 표현식은 조건이 적용되는 변수만 참조할 수 있으며 오류를 생성해서는 절대 안 돼요.

condition이 false로 평가되면 Nomad는 error_message에 주어진 문장들을 포함하는 오류 메시지를 생성해요. 오류 메시지 문자열은 실패한 제약을 설명하는 전체 문장 하나 이상이어야 하며, (알파벳이 허락한다면) 대문자로 시작하고 마침표나 물음표로 끝나야 해요.

여러 validation 블록을 선언할 수 있으며, 그 경우 실패한 모든 조건에 대한 오류 메시지가 반환돼요.

job 변수에 값 할당 (Assigning Values to job Variables)

구성에서 변수를 선언하면 다음으로 변수를 설정할 수 있어요.

  • 개별적으로, -var foo=bar 명령줄 옵션으로.
  • 명령줄에 지정된 변수 정의 파일에서(-var-file=input.vars 사용).
  • 환경 변수로, 예: NOMAD_VAR_foo=bar

다음 절들에서 이 옵션들을 더 자세히 설명해요.

명령줄의 변수 (Variables on the Command Line)

명령줄에서 개별 변수를 지정하려면 nomad job run 명령을 실행할 때 -var 옵션을 사용하세요.

$ nomad job run -var="image_id=nginx:1.19" example.nomad.hcl

-var 옵션은 단일 명령에서 몇 번이든 사용할 수 있어요.

명령줄로 변수를 할당할 계획이라면 빈 블록 대신 기본 타입을 최소한 설정할 것을 강력히 권장해요. 이는 HCL 파서가 무엇이 설정되고 있는지 이해하는 데 도움이 돼요. 그렇지 않으면 인터프리터는 명령줄에 설정된 변수가 문자열이라고 가정해요.

변수 정의 파일 (Variable Definitions Files)

많은 변수를 설정하려면 그 값들을 변수 정의 파일에 지정하고 -var-file로 명령줄에서 그 파일을 지정하는 것이 더 편리해요.

$ nomad job run -var-file="testing.vars" example.nomad.hcl

변수 정의 파일은 같은 HCL 기본 문법을 사용하지만 변수 이름 할당으로만 구성돼요.

image_id = "nginx:1.19"
labels = [
  "testing",
  "internal",
]

또는 파일을 JSON 객체로 만들 수도 있으며, 루트 객체의 속성이 변수 이름에 대응돼요.

{
  "image_id": "nginx:1.19",
  "labels": ["testing", "internal"]
}

환경 변수 (Environment Variables)

다른 변수 정의 방식의 대비책으로, Nomad는 자체 프로세스의 환경에서 NOMAD_VAR_ 뒤에 선언된 변수 이름이 붙은 환경 변수를 검색해요.

이것은 자동화에서 Nomad를 실행하거나 같은 변수로 일련의 Nomad 명령을 연속 실행할 때 유용해요. 예를 들어 Unix 시스템의 bash 프롬프트에서:

$ export NOMAD_VAR_image_id=nginx:1.19
$ nomad job run example.nomad.hcl
...

환경 변수 이름이 대소문자를 구분하는 운영 체제에서 Nomad는 구성에 주어진 대로 변수 이름을 정확히 일치시켜요. 따라서 필요한 환경 변수 이름은 위 예제처럼 대문자와 소문자가 섞여 있을 때가 많아요.

복잡한 타입 값 (Complex-typed Values)

변수 값이 변수 정의 파일에 제공되면 Nomad의 일반 문법을 사용해 리스트나 맵 같은 복잡한 타입 값을 할당할 수 있어요.

-var 명령줄 옵션과 환경 변수에는 몇 가지 특별한 규칙이 적용돼요. 편의를 위해 Nomad는 기본적으로 -var와 환경 변수 값을 따옴표가 필요 없는 리터럴 문자열로 해석해요.

$ export NOMAD_VAR_image_id=nginx:1.19

하지만 입력 변수가 복잡한 값(리스트, 집합, 맵, 객체, 튜플)을 요구하는 타입 제약을 사용한다면, Nomad는 대신 변수 정의 파일 안에서 사용되는 것과 같은 문법으로 그 값을 파싱하려고 시도해요. 이는 셸의 문자열 이스케이프 규칙에 주의해야 한다는 뜻이에요.

$ export NOMAD_VAR_availability_zone_names='["us-west-1b","us-west-1d"]'

가독성을 위해, 그리고 셸 이스케이프를 걱정할 필요를 피하기 위해 복잡한 변수 값은 항상 변수 정의 파일로 설정하는 것을 권장해요.

변수 정의 우선순위 (Variable Definition Precedence)

위의 변수 설정 메커니즘들은 어떤 조합으로든 함께 사용할 수 있어요.

Nomad는 다음 순서로 변수를 로드하며, 나중 소스가 이전 소스보다 우선해요.

  • 환경 변수(최저 우선순위)
  • 명령줄의 -var 및 -var-file 옵션들(제공된 순서대로). (최고 우선순위)

같은 변수가 서로 다른 메커니즘으로 여러 값으로 할당되면 Nomad는 찾은 마지막 값을 사용해 이전 값을 덮어써요. 같은 변수는 단일 소스 안에서 여러 값으로 할당될 수 없다는 점에 유의하세요.

중요: 맵과 객체 값이 있는 변수는 다른 변수와 같은 방식으로 동작해요. 마지막으로 찾은 값이 이전 값을 덮어쓴다는 뜻이에요.

변수 값은 반드시 알려져 있어야 함 (A variable value must be known)

다음 변수를 예로 들어 볼게요.

variable "foo" {
  type = string
}

여기서 foo는 알려진 값이 있어야 하지만, default를 null로 설정하면 이 동작을 선택 사항으로 만들 수 있어요.

기본 없음 default = null default = "xy"
foo 미사용 오류, "foo needs to be set" - -
var.foo 오류, "foo needs to be set" null xy
NOMAD_VAR_foo=yz var.foo yz yz yz
-var foo=yz var.foo yz yz yz

더 알아보기 (Learn more)

  • HCL locals 참조를 확인해 보세요.