provisioner 블록
provisioner 블록
provisioner 블록에 대한 레퍼런스 정보를 제공하는 문서예요. 프로비저너를 어떻게 구성하고, 특정 소스에서만 실행하거나 오류 시 처리하는 방법 등을 다룹니다.
출처: Packer 공식 문서
본문
설명 (Description)
provisioner 블록은 프로비저너를 구성하는 방법을 정의해요. 프로비저너는 부팅 후 머신 이미지를 설치하고 구성하기 위해 내장 및 서드파티 소프트웨어를 사용합니다. 프로비저너는 시스템을 사용할 준비가 된 상태로 만들어 줍니다.
사용 가능한 프로비저너 목록은 Provisioners 섹션에서 찾을 수 있어요.
# builds.pkr.hcl
build {
# ...
provisioner "shell" {
inline = [
"echo provisioning all the things",
"echo the value of 'foo' is '${var.foo}'",
]
}
}
특정 소스에서 실행 (Run on Specific Sources)
only 또는 except 구성을 사용해 프로비저너를 특정 소스에서만 실행할 수 있어요. 이 두 구성은 예상대로 동작합니다. only는 지정된 소스에서만 프로비저너를 실행하고 except는 지정된 소스를 제외한 나머지에서 실행합니다. only가 사용된 예시가 아래에 있지만, except의 사용도 사실상 동일합니다.
# builds.pkr.hcl
source "amazon-ebs" "first-example" {
#...
}
source "amazon-ebs" "second-example" {
#...
}
build {
sources = [
"source.amazon-ebs.first-example",
"source.amazon-ebs.second-example",
]
provisioner "shell" {
# This provisioner only runs for the 'first-example' source.
only = ["amazon-ebs.first-example"]
inline = [
"echo provisioning all the things",
"echo the value of 'foo' is '${var.foo}'",
]
}
provisioner "shell" {
# This runs with all sources.
inline = [
"echo Hi World!"
]
}
}
only와 except 안의 소스 이름은 source. 접두어를 붙이지 않아야 해요.
only 또는 except 안의 값은 빌더 타입도 빌드 이름도 아닌 소스 이름입니다.
Note: CLI에서
only와except는 빌드 이름(예: my_build.amazon-ebs.first-example)과 매칭하지만, 프로비저너에서는 소스 이름(예: amazon-ebs.third-example)과 매칭해요.
빌드별 재정의 (Build-Specific Overrides)
Packer의 목표는 동일한 머신 이미지를 만드는 것이지만, 가끔은 이미지가 결국 동일하게 수렴하기 전에 머신들이 서로 다른 상태인 기간이 필요할 때가 있어요. 이런 경우 빌드에 따라 프로비저너에 다른 구성이 필요할 수 있습니다. 이는 빌드별 재정의(build-specific overrides)로 할 수 있어요.
이것이 필요한 예시로 EC2 AMI와 VMware 머신을 모두 빌드하는 경우가 있어요. 소스 EC2 AMI는 기본적으로 관리자 권한을 가진 사용자를 설정할 수 있지만, VMware 머신에는 그런 권한이 없습니다. 이 경우 shell 스크립트를 다르게 실행해야 할 수 있어요. 물론 목표는 shell 스크립트가 이 두 이미지를 동일하게 수렴시키는 것이지만, 처음에는 다르게 실행할 필요가 있을 수 있어요.
이 예시는 아래와 같습니다.
source "null" "example1" {
communicator = "none"
}
source "null" "example2" {
communicator = "none"
}
source "null" "example3" {
communicator = "none"
}
build {
sources = ["source.null.example2", "source.null.example3"]
source "source.null.example1" {
// Give a name to this source
name = "renamed"
}
provisioner "shell-local" {
inline = ["echo not overridden"]
override = {
example3 = {
inline = ["echo overrides for example3"]
}
// Refer to the source with the given name
renamed = {
inline = ["echo overrides for renamed"]
}
}
}
}
보시다시피 override 키가 사용돼요. 이 키의 값은 또 하나의 HCL 속성 맵이며, 키는 소스 정의의 이름입니다. 그 값은 다시 또 하나의 HCL 속성 맵이에요. 이 HCL 속성 맵은 평소처럼 프로비저너 구성을 담습니다. 이 구성은 기본 프로비저너 구성에 병합됩니다.
오류 시 프로비저너 (On Error Provisioner)
선택적으로 error-cleanup-provisioner라고 불리는 단일 특수 프로비저너를 만들 수 있어요. 이 프로비저너는 일반 프로비저닝 실행이 실패하지 않는 한 실행되지 않습니다. 일반 프로비저닝 실행이 실패하면 이 특수 오류 프로비저너가 인스턴스가 종료되기 전에 실행돼요. 이를 통해 Packer가 스스로 정리하지 못할 수 있는 마지막 순간의 변경과 정리 동작을 할 수 있습니다.
예를 들어 사용자는 이 프로비저너를 사용해 인스턴스가 빌드 실행 중 연결했던 어떤 서비스에서도 제대로 구독 해지되었는지 확인할 수 있어요.
오류 정리 스크립트의 장난감 예시:
source "null" "example" {
communicator = "none"
}
build {
sources = ["source.null.example"]
provisioner "shell-local" {
inline = ["exit 2"]
}
error-cleanup-provisioner "shell-local" {
inline = ["echo 'rubber ducky'> ducky.txt"]
}
}
실행 전에 일시 중지 (Pausing Before Running)
어떤 프로비저너에서는 실행 전에 일정 시간 동안 일시 중지하는 것이 바람직할 때가 있어요. 특히 프로비저너가 머신을 재부팅하는 경우, 다음 프로비저너를 시작하기 전에 일정 시간 기다리고 싶을 수 있습니다.
Packer 템플릿의 모든 프로비저너 정의는 특수 구성 pause_before를 받을 수 있으며, 이는 해당 프로비저너를 실행하기 전에 일시 중지할 시간이에요. 기본적으로 일시 중지는 없습니다. 예시는 아래와 같습니다.
# builds.pkr.hcl
build {
# ...
provisioner "shell" {
inline = [
"echo provisioning all the things",
"echo the value of 'foo' is '${var.foo}'",
]
pause_before = "10s"
}
}
위 프로비저너의 경우 Packer는 shell 스크립트를 업로드하고 실행하기 전에 10초를 기다려요.
오류 시 재시도 (Retry on error)
어떤 프로비저너에서는 실패할 때 재시도하는 것이 바람직한 경우가 있어요. 특히 프로비저너가 아직 끝나지 않은 외부 프로세스에 의존하는 경우에 그렇습니다.
Packer 템플릿의 모든 프로비저너 정의는 특수 구성 max_retries를 받을 수 있으며, 이는 프로비저너가 오류 시 재시도하는 최대 횟수예요. 기본적으로 max_retries는 0이고 오류 시 재시도가 없습니다. 예시는 아래와 같습니다.
# builds.pkr.hcl
build {
# ...
provisioner "shell" {
inline = [
"echo provisioning all the things",
"echo the value of 'foo' is '${var.foo}'",
]
max_retries = 5
}
}
위 프로비저너의 경우 Packer는 실패가 멈출 때까지 최대 다섯 번 재시도해요. 다섯 번 재시도한 뒤에도 프로비저너가 여전히 실패하면 전체 빌드가 실패합니다.
오류 후 계속 (Continue after an error)
Packer 템플릿의 모든 프로비저너 정의는 continue_on_error를 true로 설정해 그 프로비저너가 실패한 뒤에도 빌드를 계속할 수 있어요. Packer는 max_retries를 모두 소진한 뒤에 이 설정을 적용합니다.
build {
# ...
provisioner "shell" {
inline = ["exit 1"]
continue_on_error = true
}
}
continue_on_error는 프로비저너가 실패한 뒤에도 이후 빌드 단계가 안전하게 실행될 수 있을 때만 사용하세요.
타임아웃 (Timeout)
때로 커맨드가 예상보다 훨씬 오래 걸릴 수 있어요.
Packer 템플릿의 모든 프로비저너 정의는 특수 구성 timeout을 받을 수 있으며, 이는 프로비저너가 실패한 것으로 간주하기 전에 기다리는 시간이에요. 기본적으로 타임아웃은 없습니다. 예시는 아래와 같습니다.
# builds.pkr.hcl
build {
# ...
provisioner "shell" {
inline = [
"echo provisioning all the things",
"echo the value of 'foo' is '${var.foo}'",
]
timeout = "5m"
}
}
위 프로비저너의 경우 Packer는 스크립트가 5분을 넘기면 취소합니다.
타임아웃은 디버그 모드에서는 효과가 없어요.
빌드 컨텍스트 변수 (Build Contextual Variables)
Packer는 프로비저너에서 연결 정보와 기본 인스턴스 상태 정보에 접근할 수 있게 해 줘요. 이 정보는 build 변수에 저장됩니다. Contextual Variables 문서를 확인해 사용법과 예시를 더 알아보세요.