JSON 템플릿 엔진 참조

JSON 템플릿 엔진 참조

이 주제는 JSON 템플릿을 처리하는 Packer 엔진을 설명해요.

출처: Packer 공식 문서

본문

참고: 이 페이지는 구식 스타일의 JSON Packer 템플릿에 대한 내용이에요. JSON 템플릿은 여전히 Packer 코어에서 지원되지만, Packer 코어에 추가된 새 기능은 JSON 템플릿에 구현되지 않을 수 있어요. Packer로 최상의 경험을 얻으려면 편한 때 빠르게 HCL 템플릿으로 전환하는 것을 권장해요. 템플릿 업그레이드를 돕기 위해 hcl2_upgrade 명령을 작성해두었어요.

설명 (Description)

템플릿 안의 모든 문자열은 공통 Packer 템플릿 엔진에 의해 처리돼요. 이 엔진은 변수와 함수를 사용해 런타임에 구성 파라미터의 값을 수정해요.

템플릿의 문법은 다음 규칙을 사용해요:

  • 템플릿과 관련된 것은 모두 이중 중괄호 안에서 이루어져요: {{ }}.
  • 함수는 중괄호 안에 직접 지정돼요. 예: {{timestamp}}.
  • 템플릿 변수는 마침표 접두사와 대문자로 표기돼요. 예: {{.Variable}}.

함수 (Functions)

함수는 문자열 안에서 그리고 문자열에 대해 작업을 수행해요. 예를 들어 {{timestamp}} 함수는 어떤 문자열에서든 현재 타임스탬프를 생성하는 데 사용할 수 있어요. 이는 AMI 이름처럼 고유한 키를 요구하는 구성에 유용해요. AMI 이름을 My Packer AMI {{timestamp}}처럼 설정하면 AMI 이름이 초 단위까지 고유해져요. 1초보다 더 세밀한 단위가 필요하다면 {{uuid}}를 사용해야 해요. 예를 들어 같은 템플릿에 여러 빌더가 있을 때 그렇죠.

다음은 참고용으로 사용 가능한 함수의 전체 목록이에요:

  • build_name - 실행 중인 빌드의 이름.

  • build_type - 현재 사용 중인 빌더의 타입.

  • clean_resource_name - 이미지 이름은 특정 문자만 포함할 수 있고 최대 길이가 있어요(GCE 63, Azure 80). clean_resource_name은 대문자를 소문자로 변환하고 불법 문자를 "-" 문자로 대체해요. 예: "mybuild-{{isotime | clean_resource_name}}"은 mybuild-2017-10-18t02-06-30z가 돼요.

    참고: 유효한 Azure 이미지 이름은 정규식 ^[^_\\W][\w-._)]{0,79}$와 일치해야 해요. 참고: 유효한 GCE 이미지 이름은 정규식 (?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?)와 일치해야 해요.

    이 엔진은 최종 이미지 이름이 정규식과 일치한다는 것을 보장하지 않아요. 허용되는 최대 문자 수를 초과해도 이름을 자르지 않고, 엔진 출력의 시작과 끝이 유효한지도 검증하지 않아요. 예를 들어 "image_name": {{isotime | clean_resource_name}}는 이미지 이름이 숫자로 시작하기 때문에 빌드를 실패시킬 거예요. 그래서 위 예시에서 isotime 앞에 "mybuild"를 붙인 거예요.

    clean_resource_name의 정확한 동작은 적용되는 빌더에 따라 달라져요. 각 함수가 어떻게 동작하는지에 대한 자세한 내용은 아래 빌드별 문서를 참고하세요.

  • env - 환경 변수를 반환해요. home 변수 사용 예시를 참고하세요.

  • build - 이 엔진은 프로비저너와 포스트-프로세서에서 연결 정보와 기본 인스턴스 상태 정보를 제공하는 특수 변수에 접근할 수 있게 해 줘요. 사용 예시:

    {
      "type": "shell-local",
      "environment_vars": ["TESTVAR={{ build `PackerRunUUID`}}"],
      "inline": ["echo $TESTVAR"]
    }
    

    요청할 수 있는 유효한 변수는 다음과 같아요:

    • ID - 프로비저닝되는 VM을 나타내요. 예를 들어 Amazon에서는 인스턴스 ID, DigitalOcean에서는 Droplet ID, VMware에서는 VM 이름이에요.

    • Host, Port, User, Password - Packer가 머신에 접근하기 위해 사용하는 호스트·포트·사용자·비밀번호. shell local 프로비저너로 프로비저닝된 인스턴스에 대해 Ansible이나 Inspec을 실행할 때 유용해요.

    • ConnType - 사용 중인 커뮤니케이터의 타입. 예를 들어 SSH 커뮤니케이터의 경우 "ssh"가 될 거예요.

    • PackerRunUUID - 현재 빌드의 고유 ID. 빌드 아티팩트를 지정하는 데 사용할 수 있어요. 예를 들어 여러 빌드가 동시에 실행되어 같은 아티팩트를 만들 때, 이 아티팩트들을 빌드의 고유 ID로 이름 지어 구분할 수 있어요.

    • PackerHTTPIP, PackerHTTPPort, PackerHTTPAddr - Packer가 "http" 디렉터리의 항목을 VM에 제공하기 위해 만드는 파일 서버의 HTTP IP·포트·주소. HTTP 주소는 IP:PORT 형식으로 표시돼요.

    • SSHPublicKey와 SSHPrivateKey - Packer가 인스턴스에 연결하기 위해 사용하는 공용·개인 키. 이들은 SSH 커뮤니케이터에만 고유하며, 다른 커뮤니케이터를 사용할 때는 설정되지 않아요. SSHPublicKey와 SSHPrivateKey는 이스케이프 시퀀스와 특수 문자를 포함할 수 있으므로 의외의 동작을 피하려면 그 출력을 작은따옴표로 감싸야 해요. 예를 들어:

      { ... "provisioners": [{
        "type": "shell",
        "inline": [ "echo '{{ build `SSHPrivateKey`}}' > /tmp/packer-session.pem" ]
        }]
      }
      

    역호환성을 위해 WinRMPassword도 이 엔진을 통해 사용할 수 있지만, 더 일반적인 Password를 사용하는 것과 다르지 않아요.

    이 함수는 프로비저너 안의 특정 옵션 안에서만 사용하기 위한 것이에요. 해당 옵션들은 프로비저너 문서에서 템플릿 엔진으로 나열될 거예요.

    빌더별 빌더 변수에 대해서는 빌더 문서도 참고하세요:

    • Amazon EC2: chroot, EBS Volume, EBS, EBS Surrogate, Instance.

    이 엔진은 베타 상태예요. 문제나 요청은 GitHub의 Packer 이슈 트래커에 보고해 주세요.

  • isotime [FORMAT] - 포맷할 수 있는 UTC 시간. 더 많은 예시는 아래의 isotime 형식 참조에서 볼 수 있어요.

  • strftime FORMAT - ISO C 표준 형식 FORMAT을 사용해 포맷된 UTC 시간. 사용 가능한 형식 지정자의 목록은 jehiah/go-strftime을 참고하세요.

    매우 많은 수의 빌더, 프로비저너, 포스트-프로세서를 사용한다면, 플러그인 구성에서 isotime 엔진을 직접 사용할 때 각 플러그인마다 타임스탬프가 조금씩 달라질 수 있다는 점에 유의하세요. 이는 타임스탬프가 초기 Packer 프로세스가 아니라 각 플러그인이 실행될 때 생성되기 때문이에요. 이를 피하고 모든 플러그인에서 타임스탬프가 일관되게 하려면, 이를 사용자 변수로 설정한 뒤 플러그인 안에서 그 사용자 변수에 접근하세요.

  • lower - 문자열을 소문자로 바꿔요.

  • packer_version - Packer 버전을 반환해요.

  • pwd - Packer를 실행하는 동안의 작업 디렉터리.

  • replace - (old, new string, n int, s) - Replace는 문자열 s에서 처음 n개의 겹치지 않는 old 인스턴스를 new로 바꾼 복사본을 반환해요.

  • replace_all - (old, new string, s) - ReplaceAll은 문자열 s에서 모든 겹치지 않는 old 인스턴스를 new로 바꾼 복사본을 반환해요.

  • split - 구분자(separator)를 사용해 입력 문자열을 분할하고 요청된 부분 문자열을 반환해요.

  • template_dir - 빌드의 템플릿이 있는 디렉터리.

  • timestamp - Packer 프로세스가 실행됐을 때의 UTC Unix 타임스탬프. 매우 많은 수의 빌더, 프로비저너, 포스트-프로세서를 사용한다면, 플러그인이 실행되는 시점(초기 Packer 프로세스가 아니라) 기준이므로 각 플러그인마다 타임스탬프가 조금씩 다를 수 있다는 점에 유의하세요. 이를 피하고 모든 플러그인에서 타임스탬프가 일관되게 하려면, 이를 사용자 변수로 설정한 뒤 플러그인 안에서 그 사용자 변수에 접근하세요.

  • uuid - 랜덤 UUID를 반환해요.

  • upper - 문자열을 대문자로 바꿔요.

  • user - 사용자 변수를 지정해요.

Amazon 빌더에 한정:

  • clean_resource_name - AMI 이름은 특정 문자만 포함할 수 있어요. 이 함수는 불법 문자를 "-" 문자로 대체해요. ":"이 유효한 AMI 이름이 아니므로 사용 예시는 {{isotime | clean_resource_name}}예요.

Google Compute 빌더에 한정:

  • clean_resource_name - GCE 이미지 이름은 특정 문자만 포함할 수 있고 최대 길이가 63이에요. 이 함수는 대문자를 소문자로 변환하고 불법 문자를 "-" 문자로 대체해요. 예: "mybuild-{{isotime | clean_resource_name}}"은 mybuild-2017-10-18t02-06-30z가 돼요.

    참고: 유효한 GCE 이미지 이름은 정규식 (?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?)와 일치해야 해요.

    이 엔진은 최종 이미지 이름이 정규식과 일치한다는 것을 보장하지 않아요. 63자를 초과해도 이름을 자르지 않고, 엔진 출력의 시작과 끝이 유효한지도 검증하지 않아요. 예를 들어 "image_name": {{isotime | clean_resource_name}}는 이미지 이름이 숫자로 시작하기 때문에 빌드를 실패시킬 거예요. 그래서 위 예시에서 isotime 앞에 "mybuild"를 붙인 거예요.

Azure 빌더에 한정:

  • clean_resource_name - Azure 관리 이미지 이름은 특정 문자만 포함할 수 있고 최대 길이가 80이에요. 이 함수는 불법 문자를 "-" 문자로 대체해요. 예: "mybuild-{{isotime | clean_resource_name}}"은 mybuild-2017-10-18t02-06-30z가 돼요.

    참고: 유효한 Azure 이미지 이름은 정규식 ^[^_\\W][\w-._)]{0,79}$와 일치해야 해요.

    이 엔진은 최종 이미지 이름이 정규식과 일치한다는 것을 보장하지 않아요. 80자를 초과해도 이름을 자르지 않고, 엔진 출력의 시작과 끝이 유효한지도 검증하지 않아요. 불법 문자를 변환할 때 이름 끝의 불법 문자는 잘라내요. 예를 들어 "managed_image_name: "My-Name::"은 "managed_image_name: "My-Name"으로 변환돼요.

템플릿 변수 (Template variables)

템플릿 변수는 빌드 시 Packer가 자동으로 설정하는 특수 변수예요. 일부 빌더, 프로비저너, 기타 컴포넌트에는 해당 컴포넌트에서만 사용할 수 있는 템플릿 변수가 있어요. 템플릿 변수는 {{ .Name }}처럼 마침표 접두사가 붙어 있어 알아볼 수 있어요. 예를 들어 shell 빌더를 사용할 때 템플릿 변수를 사용해 Packer가 셸 명령을 어떻게 실행할지 결정하는 execute_command 파라미터를 사용자 지정할 수 있어요.

{
  "provisioners": [
    {
      "type": "shell",
      "execute_command": "{{.Vars}} sudo -E -S bash '{{.Path}}'",
      "scripts": ["scripts/bootstrap.sh"]
    }
  ]
}

{{ .Vars }}와 {{ .Path }} 템플릿 변수는 각각 환경 변수 목록과 실행할 스크립트의 경로로 대체돼요.

참고: 템플릿 변수 외에도 자신만의 사용자 변수를 지정할 수 있어요. 사용자 변수에 대한 자세한 내용은 사용자 변수 문서를 참고하세요.

isotime 함수 형식 참조 (isotime Function Format Reference)

isotime 템플릿 엔진은 Go를 사용해 타임스탬프를 생성해요. Go에 익숙하지 않다면, 타임스탬프 형식을 지정하는 방식이 datetime 문자열을 포맷하는 데 익숙한 방식과는 조금 다르게 느껴질 거예요.

Go 시간 포맷 함수에 대한 전체 문서와 예시는 여기에서 찾을 수 있어요.

하지만 포맷팅의 기본은 여기서 설명할 가치가 있어요. Go 문서에서:

이들은 Time.Format과 time.Parse에서 사용하기 위한 사전 정의된 레이아웃이에요. 레이아웃에서 사용되는 참조 시간은 특정 시간이에요:

Mon Jan 2 15:04:05 MST 2006

이것은 Unix 시간 1136239445예요. MST는 GMT-0700이므로, 참조 시간은 다음과 같이 생각할 수 있어요:

01/02 03:04:05PM '06 -0700

자신만의 형식을 정의하려면 참조 시간이 자신의 방식대로 포맷되었을 때 어떻게 보일지 적어보세요. 예를 들면 ANSIC, StampMicro, Kitchen 같은 상수의 값을 참고하세요. 모델은 참조 시간이 어떻게 보이는지 보여주는 것이므로 Format과 Parse 메서드가 일반 시간 값에 같은 변환을 적용할 수 있어요.

그렇다면 Packer 템플릿 함수에서는 어떻게 보일까요? isotime 함수를 사용해 변수를 선언하는 방법의 예시는 다음과 같아요.

"variables": {
  "myvar": "packer-{{isotime `2006-01-02 03:04:05`}}"
}

다음 예시를 packer 템플릿이나 packer console에서 수정해보면서 서로 다른 타임스탬프를 설정하는 방법을 익힐 수 있어요:

입력 출력
"packer-{{isotime 2006-01-02}}" "packer-2021-05-17"
"packer-{{isotime Jan-_2-15:04:05.000}}" "packer-May-17-23:40:16.786"
"packer-{{isotime 3:04PM}}" "packer-11:40PM"
"{{ isotime }}" "June 7, 7:22:43pm 2014"
"{{isotime 2006-01-02}}" "2014-06-07"
"{{isotime Mon 1504}}" "Sat 1922"
"{{isotime 02-Jan-06 03_04_05}}" "07-Jun-2014 07_22_43"
"{{isotime Hour15Year200603}}" "Hour19Year201407"

isotime 함수의 포맷팅은 마법의 참조 날짜 Mon Jan 2 15:04:05 -0700 MST 2006를 사용하며, 이는 다음과 같이 분해돼요:

요일 월 날짜 시 분 초 연도 시간대
숫자 - 01 02 03 (15) 04 05 06 -0700
텍스트 Monday (Mon) January (Jan) - - - - - MST

괄호 안의 값은 축약형 또는 24시간제 시계 값이에요.

isotime은 항상 UTC 시간이므로 "-0700"이 항상 "+0000"으로 포맷된다는 점에 유의하세요.

split 함수 형식 참조 (split Function Format Reference)

split 함수는 입력 문자열, 구분자 문자열, 숫자 컴포넌트 값을 받아 요청된 부분 문자열을 반환해요.

현재는 함수를 중첩할 수 없기 때문에 사용자 변수에는 split 함수를 사용할 수 없다는 점에 유의하세요. 이 함수는 build_name 같은 빌더 변수에 사용하기 위한 것이에요. split한 사용자 변수가 필요하다면 별도의 변수를 만드는 것이 가장 좋은 방법이에요.

위 옵션을 사용한 몇 가지 예시:

build_name = foo-bar-provider

{{split build_name "-" 0}} = foo
{{split "fixed-string" "-" 1}} = string

템플릿 안에서 큰따옴표 문자는 이스케이프가 필요하다는 점에 유의하세요(이 경우 fixed-string 값에서):

{
  "post-processors": [
    [
      {
        "type": "vagrant",
        "compression_level": 9,
        "keep_input_artifact": false,
        "vagrantfile_template": "tpl/{{split build_name \"-\" 1}}.rb",
        "output": "output/{{build_name}}.box",
        "only": ["org-name-provider"]
      }
    ]
  ]
}

replace 함수 형식 참조 (replace Function Format Reference)

replace 옵션을 사용한 몇 가지 예시:

build_name = foo-bar-provider

{{ replace_all "-" "/" build_name }}  = foo/bar/provider
{{ build_name | replace "-" "/" 1 }} = foo/bar-provider