기계가 읽을 수 있는 UI 출력 참조
기계가 읽을 수 있는 UI 출력 참조 (Machine-readable UI Output Reference)
Terraform이 출력하는 기계가 읽을 수 있는 출력에 대한 참조 정보를 제공해요. -json 플래그를 사용하면 구조화된 JSON 출력 모드를 활성화할 수 있어요. 이 페이지는 각 메시지 유형과 형식을 설명해요.
출처: 문서
본문
이 주제는 Terraform이 출력하는 기계가 읽을 수 있는 출력에 대한 참조 정보를 제공해요.
소개
기본적으로 많은 Terraform 명령은 터미널 에뮬레이터에서 읽도록 의도된 구조화되지 않은 텍스트로 UI 출력을 표시해요. 이 텍스트 스트림은 통합을 위한 안정적인 인터페이스가 아니에요. 일부 명령은 정의된 인터페이스가 있는 구조화된 JSON 출력 모드를 활성화하는 -json 플래그를 지원해요.
plan, apply, refresh, test 같은 장기 실행 명령의 경우 -json 플래그는 JSON UI 메시지 스트림을 출력해요. 출력 메시지는 한 줄에 하나씩 나타나므로 소프트웨어 필터링, 결합, 수정을 통합해 원하는 대로 메시지를 처리할 수 있어요.
첫 번째 출력 메시지의 유형은 version이며 ui 키를 포함해요. 그 값은 Terraform 1.1.0 기준으로 "1.0"이에요. 이 버전의 의미는 다음과 같아요:
- 하위 호환되는 변경이나 추가 사항에 대해서는 부 버전을 증가시킬 거예요(예:
"1.1"). 향후 부 버전과의 호환성을 유지하려면 인식되지 않는 이름의 객체 속성은 무시하세요. - 하위 호환되지 않는 변경 사항에 대해서는 주 버전을 증가시킬 거예요(예:
"2.0"). 지원되지 않는 주 버전을 보고하는 입력은 거부하세요.
추가 정보는 Terraform 1.0 호환성 약속 (Terraform 1.0 Compatibility Promises)을 참조하세요.
샘플 JSON 출력
다음은 terraform apply -json을 실행한 샘플 출력이에요:
{"@level":"info","@message":"Terraform 0.15.4","@module":"terraform.ui","@timestamp":"2021-05-25T13:32:41.275359-04:00","terraform":"0.15.4","type":"version","ui":"0.1.0"}
{"@level":"info","@message":"random_pet.animal: Plan to create","@module":"terraform.ui","@timestamp":"2021-05-25T13:32:41.705503-04:00","change":{"resource":{"addr":"random_pet.animal","module":"","resource":"random_pet.animal","implied_provider":"random","resource_type":"random_pet","resource_name":"animal","resource_key":null},"action":"create"},"type":"planned_change"}
{"@level":"info","@message":"Plan: 1 to add, 0 to change, 0 to destroy.","@module":"terraform.ui","@timestamp":"2021-05-25T13:32:41.705638-04:00","changes":{"add":1,"change":0,"remove":0,"operation":"plan"},"type":"change_summary"}
{"@level":"info","@message":"random_pet.animal: Creating...","@module":"terraform.ui","@timestamp":"2021-05-25T13:32:41.825308-04:00","hook":{"resource":{"addr":"random_pet.animal","module":"","resource":"random_pet.animal","implied_provider":"random","resource_type":"random_pet","resource_name":"animal","resource_key":null},"action":"create"},"type":"apply_start"}
{"@level":"info","@message":"random_pet.animal: Creation complete after 0s [id=smart-lizard]","@module":"terraform.ui","@timestamp":"2021-05-25T13:32:41.826179-04:00","hook":{"resource":{"addr":"random_pet.animal","module":"","resource":"random_pet.animal","implied_provider":"random","resource_type":"random_pet","resource_name":"animal","resource_key":null},"action":"create","id_key":"id","id_value":"smart-lizard","elapsed_seconds":0},"type":"apply_complete"}
{"@level":"info","@message":"Apply complete! Resources: 1 added, 0 changed, 0 destroyed.","@module":"terraform.ui","@timestamp":"2021-05-25T13:32:41.869168-04:00","changes":{"add":1,"change":0,"remove":0,"operation":"apply"},"type":"change_summary"}
{"@level":"info","@message":"Outputs: 1","@module":"terraform.ui","@timestamp":"2021-05-25T13:32:41.869280-04:00","outputs":{"pets":{"sensitive":false,"type":"string","value":"smart-lizard"}},"type":"outputs"}
각 줄은 모든 메시지에 공통된 여러 키가 있는 JSON 객체로 구성돼요. 그 키들은 다음과 같아요:
@level: 보통 "info"지만 진단(diagnostics)을 표시할 때는 "error" 또는 "warn"일 수 있어요@message: 이 메시지 내용에 대한 사람이 읽을 수 있는 요약@module: UI 출력을 렌더링할 때 항상 "terraform.ui"@timestamp: 메시지가 출력된 시점의 RFC3339 타임스탬프type: 이 메시지가 어떤 종류인지 정의하고, 있을 수 있는 다른 키를 어떻게 해석할지 결정함
로그를 사용자 인터페이스로 제시하는 클라이언트는 예상치 못한 메시지 유형을 최소한 @message 필드를 사용자에게 제시함으로써 처리해야 해요.
메시지는 그것을 트리거하는 이벤트가 발생할 때 전송돼요. 이는 여러 리소스와 관련된 메시지가 (Terraform이 1보다 큰 동시성으로 실행되는 경우) 서로 섞일 수 있다는 뜻이에요. resource 객체 값을 사용해 단일 리소스에 대한 여러 메시지를 연결할 수 있어요.
메시지 유형
다음 메시지 유형이 지원돼요:
일반 메시지
version: Terraform 버전과 이후 메시지에 사용되는 스키마 버전에 대한 정보log: 구조화되지 않은 사람이 읽을 수 있는 로그 줄diagnostic: 진단 경고 또는 오류 메시지. 형식에 대한 자세한 내용은 theterraform validate문서를 참조하세요.
초기화 메시지
init 명령의 JSON 출력에서 온 메시지는 type이 init_output 또는 log(위에 문서화된 대로)일 수 있어요.
init_output 유형의 메시지에는 아래에 문서화된 추가 message_code가 있어요.
예시 출력
{"@level":"info","@message":"Terraform 1.9.0","@module":"terraform.ui","@timestamp":"2025-08-11T15:09:15.919212+02:00","terraform":"1.9.0","type":"version","ui":"1.2"}
{"@level":"info","@message":"Initializing the backend...","@module":"terraform.ui","@timestamp":"2025-08-11T13:09:15Z","message_code":"initializing_backend_message","type":"init_output"}
{"@level":"info","@message":"Initializing provider plugins...","@module":"terraform.ui","@timestamp":"2025-08-11T13:09:15Z","message_code":"initializing_provider_plugin_message","type":"init_output"}
{"@level":"info","@message":"Finding matching versions for provider: hashicorp/aws, version_constraint: \"~\u003e 6.8\"","@module":"terraform.ui","@timestamp":"2025-08-11T15:09:15.921436+02:00","type":"log"}
{"@level":"info","@message":"hashicorp/random: Reusing previous version from the dependency lock file","@module":"terraform.ui","@timestamp":"2025-08-11T15:09:16.874024+02:00","type":"log"}
{"@level":"info","@message":"Installing provider version: hashicorp/aws v6.8.0...","@module":"terraform.ui","@timestamp":"2025-08-11T15:09:18.827459+02:00","type":"log"}
{"@level":"info","@message":"Installed provider version: hashicorp/aws v6.8.0 (signed by HashiCorp)","@module":"terraform.ui","@timestamp":"2025-08-11T15:09:35.414989+02:00","type":"log"}
{"@level":"info","@message":"Installing provider version: hashicorp/random v3.7.2...","@module":"terraform.ui","@timestamp":"2025-08-11T15:09:36.363085+02:00","type":"log"}
{"@level":"info","@message":"Installed provider version: hashicorp/random v3.7.2 (signed by HashiCorp)","@module":"terraform.ui","@timestamp":"2025-08-11T15:09:42.258989+02:00","type":"log"}
{"@level":"info","@message":"Terraform has made some changes to the provider dependency selections recorded\nin the .terraform.lock.hcl file. Review those changes and commit them to your\nversion control system if they represent changes you intended to make.","@module":"terraform.ui","@timestamp":"2025-08-11T13:09:42Z","message_code":"dependencies_lock_changes_info","type":"init_output"}
{"@level":"info","@message":"Terraform has been successfully initialized!","@module":"terraform.ui","@timestamp":"2025-08-11T13:09:42Z","message_code":"output_init_success_message","type":"init_output"}
{"@level":"info","@message":"You may now begin working with Terraform. Try running \"terraform plan\" to see\nany changes that are required for your infrastructure. All Terraform commands\nshould now work.\n\nIf you ever set or change modules or backend configuration for Terraform,\nrerun this command to reinitialize your working directory. If you forget, other\ncommands will detect it and remind you to do so if necessary.","@module":"terraform.ui","@timestamp":"2025-08-11T13:09:42Z","message_code":"output_init_success_cli_message","type":"init_output"}
일반
output_init_empty_message: 빈 디렉토리가 성공적으로 초기화되었음을 나타냄output_init_success_message: [비어 있지 않은] 디렉토리가 CLI를 통해 성공적으로 초기화되었음을 나타냄output_init_success_cloud_message: [비어 있지 않은] 디렉토리가 HCP Terraform을 통해 성공적으로 초기화되었음을 나타냄output_init_success_cli_message: CLI를 통해 디렉토리가 성공적으로 초기화된 후의 다음 단계 지침output_init_success_cli_cloud_message: HCP Terraform을 통해 디렉토리가 성공적으로 초기화된 후의 다음 단계 지침
백엔드 초기화
initializing_terraform_cloud_message: HCP Terraform(cloud백엔드) 초기화 중 진행 상황을 나타냄initializing_backend_message: 백엔드 초기화 중 진행 상황을 나타냄backend_configured_success: 백엔드가 처음으로 성공적으로 구성되었음을 나타냄
프로바이더 설치
initializing_provider_plugin_message: 프로바이더 설치 중 진행 상황을 나타냄reusing_version_during_state_provider_init: 상태 기반 프로바이더 설치 중 프로바이더 버전 재사용을 나타냄provider_already_installed_message: 설치 중 이미 설치된 프로바이더를 나타냄built_in_provider_available_message: 설치 중 사용 중인 내장 프로바이더를 나타냄installing_provider_message: 프로바이더가 (원격 위치에서) 설치되고 있음을 나타냄lock_info: 설치된 프로바이더에 대해 새 잠금 파일이 생성되었음을 설명함dependencies_lock_changes_info: 잠금 파일이 변경되었음을 설명함(예: 프로바이더 설치 또는 업그레이드의 결과)
모듈 설치
copying_configuration_message:-from-module플래그를 사용할 때 모듈 내용 복사 중 진행 상황을 나타냄upgrading_modules_message:-upgrade플래그를 사용할 때 모듈 업그레이드 중 진행 상황을 나타냄initializing_modules_message: 모듈 설치 중 진행 상황을 나타냄
작업 결과
resource_drift: Terraform 외부에서 이루어진 단일 리소스에 대한 감지된 변경을 설명함planned_change: 단일 리소스에 대한 계획된 변경을 설명함change_summary: 모든 계획되거나 적용된 변경의 요약outputs: 모든 루트 모듈 출력 목록
리소스 진행 상황
apply_start,apply_progress,apply_complete,apply_errored: 단일 리소스가 apply를 통해 진행되는 상황을 나타내는 메시지 시퀀스provision_start,provision_progress,provision_complete,provision_errored: 단일 프로비저너 단계의 진행 상황을 나타내는 메시지 시퀀스planned_action_invocation: 작업(action)이 호출되었음을 나타내는 메시지refresh_start,refresh_complete: 단일 리소스가 refresh를 통해 진행되는 상황을 나타내는 메시지 시퀀스
테스트 결과
test_abstract: Terraform이 실행하는 테스트 작업을 설명함test_file: 완료된 테스트 파일의 상태를 설명함test_run: 테스트 파일 내 완료된run블록의 상태를 설명함test_cleanup: 완료된 테스트 파일 후 테스트 정리의 결과를 설명함test_summary: 완료된 테스트 작업의 전체 상태를 설명함test_plan:command = plan일 때 주어진run블록의 출력을 설명함test_state:command = apply일 때 주어진run블록의 출력을 설명함test_interrupt: 중단된 테스트 작업의 결과를 설명함
버전 메시지
기계가 읽을 수 있는 UI 명령 출력은 항상 version 메시지로 시작해요. 다음 메시지별 키가 정의돼요:
예시
{
"@level": "info",
"@message": "Terraform 0.15.4",
"@module": "terraform.ui",
"@timestamp": "2021-05-25T13:32:41.275359-04:00",
"terraform": "0.15.4",
"type": "version",
"ui": "0.1.0"
}
리소스 드리프트
계획 중에 드리프트가 감지되면 Terraform은 Terraform 외부에서 변경된 각 리소스에 대해 resource_drift 메시지를 발행해요. 이 메시지는 다음 키가 있는 임베디드 change 객체를 가져요:
resource: 변경될 리소스의 주소를 설명하는 객체. 자세한 내용은 아래 resource 객체를 참조하세요.action: 리소스에 대해 계획된 작업. 값:update,delete.
이 메시지는 변경이 계획되게 만든 정확한 변경에 대한 세부 정보는 포함하지 않아요. 그 정보는 JSON 계획 출력 (the JSON plan output)에 있어요.
예시
{
"@level": "info",
"@message": "random_pet.animal: Drift detected (update)",
"@module": "terraform.ui",
"@timestamp": "2021-05-25T13:32:41.705503-04:00",
"change": {
"resource": {
"addr": "random_pet.animal",
"module": "",
"resource": "random_pet.animal",
"implied_provider": "random",
"resource_type": "random_pet",
"resource_name": "animal",
"resource_key": null
},
"action": "update"
},
"type": "resource_drift"
}
계획된 변경
계획이 끝날 때 또는 apply 전에 Terraform은 적용할 변경이 있는 각 리소스에 대해 planned_change 메시지를 발행해요. 이 메시지는 다음 키가 있는 임베디드 change 객체를 가져요:
resource: 변경될 리소스의 주소를 설명하는 객체. 자세한 내용은 아래 resource 객체를 참조하세요.previous_resource: 이 변경이 구성 기반 이동을 포함한다면 리소스의 이전 주소를 설명하는 객체action: 리소스에 대해 계획된 작업. 값:noop,create,read,update,replace,delete,move,import.reason: 변경에 대한 선택적 이유.replace또는delete작업일 때만 사용됨. 값:tainted: 리소스가 tainted로 표시되었음requested: 사용자가 예를 들어-replace계획 플래그를 통해 리소스 교체를 요청했음cannot_update: 구성 변경으로 리소스가 업데이트가 아닌 삭제 및 생성되어야 함delete_because_no_resource_config: 구성에 일치하는 리소스가 없음delete_because_wrong_repetition: 리소스 인스턴스 키에 구성의 해당count또는for_each가 없음delete_because_count_index: 리소스 인스턴스 키가count인자의 범위 밖에 있음delete_because_each_key: 리소스 인스턴스 키가for_each인자에 포함되지 않음delete_because_no_module: 둘러싸는 모듈 인스턴스가 구성에 없음
이 메시지는 변경이 계획되게 만든 정확한 변경에 대한 세부 정보는 포함하지 않아요. 그 정보는 JSON 계획 출력 (the JSON plan output)에 있어요.
예시
{
"@level": "info",
"@message": "random_pet.animal: Plan to create",
"@module": "terraform.ui",
"@timestamp": "2021-05-25T13:32:41.705503-04:00",
"change": {
"resource": {
"addr": "random_pet.animal",
"module": "",
"resource": "random_pet.animal",
"implied_provider": "random",
"resource_type": "random_pet",
"resource_name": "animal",
"resource_key": null
},
"action": "create"
},
"type": "planned_change"
}
변경 요약
Terraform은 plan 또는 apply 작업이 완료되면 변경 요약을 출력해요. 두 메시지 유형 모두 changes 객체를 포함하며, 이 객체는 다음 키를 가져요:
add: 생성될 리소스 수(교체의 일부로 포함)change: 제자리에서 변경될 리소스 수remove: 파괴될 리소스 수(교체의 일부로 포함)operation:plan,apply또는destroy중 하나
예시
{
"@level": "info",
"@message": "Apply complete! Resources: 1 added, 0 changed, 0 destroyed.",
"@module": "terraform.ui",
"@timestamp": "2021-05-25T13:32:41.869168-04:00",
"changes": {
"add": 1,
"change": 0,
"remove": 0,
"operation": "apply"
},
"type": "change_summary"
}
출력
성공적인 plan 또는 apply 후에 유형 outputs인 메시지가 모든 루트 모듈 출력 값의 값을 포함해요. 이 메시지는 outputs 객체를 포함하며, 그 키는 출력 이름이에요. 출력 값은 다음 키를 가진 객체예요:
action: 계획된 출력의 경우, 출력에 대해 취해질 작업. 값:noop,create,update,deletevalue: 적용된 출력의 경우, JSON으로 인코딩된 출력 값type: 적용된 출력의 경우, 감지된 출력 값의 HCL 유형sensitive: 불리언 값. 출력이 민감하고 기본적으로 UI에서 숨겨져야 하면true
sensitive 출력도 여전히 value 필드를 포함한다는 점에 유의하세요. 통합 소프트웨어는 주어진 사용 사례에 적절하게 민감도 값을 존중해야 해요.
예시
{
"@level": "info",
"@message": "Outputs: 1",
"@module": "terraform.ui",
"@timestamp": "2021-05-25T13:32:41.869280-04:00",
"outputs": {
"pets": {
"sensitive": false,
"type": "string",
"value": "smart-lizard"
}
},
"type": "outputs"
}
작업 메시지
리소스에 대한 Terraform 작업을 수행하면 종종 여러 메시지가 발행돼요. 메시지 유형은 다음과 같아요:
apply_start: 리소스에 대한 변경 적용 시작 시apply_progress: 주기적으로 경과 시간 출력 표시apply_complete: 작업 완료 성공 시apply_errored: 작업 중 오류 발생 시provision_start: 프로비저너 단계 시작 시provision_progress: 프로비저너 출력 시provision_complete: 프로비저닝 성공 시provision_errored: 프로비저닝 중 오류 발생 시refresh_start: refresh 중 리소스 읽기 시refresh_complete: refresh 성공 시ephemeral_op_start: 임시(ephemeral) 리소스 작업 시작 시ephemeral_op_progress: 임시 리소스 작업 중 주기적으로 경과 시간 출력 표시ephemeral_op_complete: 임시 리소스 작업 완료 성공 시ephemeral_op_errored: 임시 리소스 작업 중 오류 발생 시
이러한 각 메시지는 hook 객체를 가지며, 각 유형에 따라 필드가 달라져요. 모든 훅은 작업의 대상인 리소스를 식별하는 resource 객체를 가져요.
Apply 시작
apply_start 메시지 hook 객체는 다음 키를 가져요:
resource: 리소스를 식별하는resource객체action: 리소스에 대해 취해질 작업. 값:noop,create,read,update,replace,deleteid_key및id_value: 리소스의 이 인스턴스를 식별하는 데 사용하는 키/값 쌍. 알 수 없으면 생략
예시
{
"@level": "info",
"@message": "random_pet.animal: Creating...",
"@module": "terraform.ui",
"@timestamp": "2021-05-25T13:32:41.825308-04:00",
"hook": {
"resource": {
"addr": "random_pet.animal",
"module": "",
"resource": "random_pet.animal",
"implied_provider": "random",
"resource_type": "random_pet",
"resource_name": "animal",
"resource_key": null
},
"action": "create"
},
"type": "apply_start"
}
Apply 진행 상황
apply_progress 메시지 hook 객체는 다음 키를 가져요:
resource: 리소스를 식별하는resource객체action: 리소스에 대해 취해지고 있는 작업. 값:noop,create,read,update,replace,deleteelapsed_seconds: apply 작업이 시작된 후 경과한 시간. 정수 초로 표현
예시
{
"@level": "info",
"@message": "null_resource.none[4]: Still creating... [30s elapsed]",
"@module": "terraform.ui",
"@timestamp": "2021-03-17T09:34:26.222465-04:00",
"hook": {
"resource": {
"addr": "null_resource.none[4]",
"module": "",
"resource": "null_resource.none[4]",
"implied_provider": "null",
"resource_type": "null_resource",
"resource_name": "none",
"resource_key": 4
},
"action": "create",
"elapsed_seconds": 30
},
"type": "apply_progress"
}
Apply 완료
apply_complete 메시지 hook 객체는 다음 키를 가져요:
resource: 리소스를 식별하는resource객체action: 리소스에 대해 취해진 작업. 값:noop,create,read,update,replace,deleteid_key및id_value: 리소스의 이 인스턴스를 식별하는 데 사용하는 키/값 쌍. 알 수 없으면 생략elapsed_seconds: apply 작업이 시작된 후 경과한 시간. 정수 초로 표현
예시
{
"@level": "info",
"@message": "random_pet.animal: Creation complete after 0s [id=smart-lizard]",
"@module": "terraform.ui",
"@timestamp": "2021-05-25T13:32:41.826179-04:00",
"hook": {
"resource": {
"addr": "random_pet.animal",
"module": "",
"resource": "random_pet.animal",
"implied_provider": "random",
"resource_type": "random_pet",
"resource_name": "animal",
"resource_key": null
},
"action": "create",
"id_key": "id",
"id_value": "smart-lizard",
"elapsed_seconds": 0
},
"type": "apply_complete"
}
Apply 오류
apply_errored 메시지 hook 객체는 다음 키를 가져요:
resource: 리소스를 식별하는resource객체action: 리소스에 대해 취해진 작업. 값:noop,create,read,update,replace,deleteelapsed_seconds: apply 작업이 시작된 후 경과한 시간. 정수 초로 표현
오류의 정확한 세부 정보는 별도의 diagnostic 메시지로 렌더링돼요.
예시
{
"@level": "info",
"@message": "null_resource.none[0]: Creation errored after 10s",
"@module": "terraform.ui",
"@timestamp": "2021-03-26T16:38:54.013910-04:00",
"hook": {
"resource": {
"addr": "null_resource.none[0]",
"module": "",
"resource": "null_resource.none[0]",
"implied_provider": "null",
"resource_type": "null_resource",
"resource_name": "none",
"resource_key": 0
},
"action": "create",
"elapsed_seconds": 10
},
"type": "apply_errored"
}
Provision 시작
provision_start 메시지 hook 객체는 다음 키를 가져요:
resource: 리소스를 식별하는resource객체provisioner: 프로비저너 유형
예시
{
"@level": "info",
"@message": "null_resource.none[0]: Provisioning with 'local-exec'...",
"@module": "terraform.ui",
"@timestamp": "2021-03-26T16:38:43.997431-04:00",
"hook": {
"resource": {
"addr": "null_resource.none[0]",
"module": "",
"resource": "null_resource.none[0]",
"implied_provider": "null",
"resource_type": "null_resource",
"resource_name": "none",
"resource_key": 0
},
"provisioner": "local-exec"
},
"type": "provision_start"
}
Provision 진행 상황
provision_progress 메시지 hook 객체는 다음 키를 가져요:
resource: 리소스를 식별하는resource객체provisioner: 프로비저너 유형output: 프로비저너의 출력 로그
프로비저너에서 받은 각 로그 줄에 대해 하나의 provision_progress 메시지가 출력돼요.
예시
{
"@level": "info",
"@message": "null_resource.none[0]: (local-exec): Executing: [\"/bin/sh\" \"-c\" \"sleep 10 && exit 1\"]",
"@module": "terraform.ui",
"@timestamp": "2021-03-26T16:38:43.997869-04:00",
"hook": {
"resource": {
"addr": "null_resource.none[0]",
"module": "",
"resource": "null_resource.none[0]",
"implied_provider": "null",
"resource_type": "null_resource",
"resource_name": "none",
"resource_key": 0
},
"provisioner": "local-exec",
"output": "Executing: [\"/bin/sh\" \"-c\" \"sleep 10 && exit 1\"]"
},
"type": "provision_progress"
}
Provision 완료
provision_complete 메시지 hook 객체는 다음 키를 가져요:
resource: 리소스를 식별하는resource객체provisioner: 프로비저너 유형
예시
{
"@level": "info",
"@message": "null_resource.none[0]: (local-exec) Provisioning complete",
"@module": "terraform.ui",
"@timestamp": "2021-03-17T09:34:06.239043-04:00",
"hook": {
"resource": {
"addr": "null_resource.none[0]",
"module": "",
"resource": "null_resource.none[0]",
"implied_provider": "null",
"resource_type": "null_resource",
"resource_name": "none",
"resource_key": 0
},
"provisioner": "local-exec"
},
"type": "provision_complete"
}
Provision 오류
provision_errored 메시지 hook 객체는 다음 키를 가져요:
resource: 리소스를 식별하는resource객체provisioner: 프로비저너 유형
예시
{
"@level": "info",
"@message": "null_resource.none[0]: (local-exec) Provisioning errored",
"@module": "terraform.ui",
"@timestamp": "2021-03-26T16:38:54.013572-04:00",
"hook": {
"resource": {
"addr": "null_resource.none[0]",
"module": "",
"resource": "null_resource.none[0]",
"implied_provider": "null",
"resource_type": "null_resource",
"resource_name": "none",
"resource_key": 0
},
"provisioner": "local-exec"
},
"type": "provision_errored"
}
작업 호출
planned_action_invocation 메시지 객체는 다음 키를 가져요:
invocation: 계획된 작업 호출에 대한 세부 정보를 포함하는 호출 객체
invocation 객체는 다음 키를 가져요:
action_addr: 호출되는 작업을 식별하는 객체action_trigger: 작업 호출을 무엇이 트리거했는지에 대한 세부 정보를 포함하는 트리거 객체lifecycle_trigger: 수명주기를 통해 작업 호출을 트리거한 리소스에 대한 세부 정보를 포함하는 트리거 객체
action_addr 객체는 다음 키를 가져요:
addr: 작업의 주소module: 작업을 포함하는 모듈action: 전체 작업 문자열implied_provider: 작업으로 암시되는 프로바이더action_type: 작업의 유형action_name: 작업의 이름action_key: 작업의 키. 있다면
action_trigger 객체는 빈 객체이며, 작업이 CLI에서 -invoke 플래그로 호출될 때 존재해요.
lifecycle_trigger 객체는 다음 키를 가져요:
triggering_resource: 작업을 트리거한 리소스를 식별하는resource객체triggering_event: 작업을 트리거한 이벤트action_trigger_block_index: 작업을 트리거한 블록의 인덱스actions_list_index: 작업 목록에서의 작업 인덱스on_failure: 실패 시 취할 작업
예시: CLI에서 -invoke 플래그로 호출된 작업
{
"@level":"info",
"@message": "planned action invocation: action.aws_lambda_invoke.api_handler",
"@module": "terraform.ui",
"@timestamp": "2026-07-30T15:18:39.254843+01:00",
"invocation": {
"action_addr": {
"addr": "action.aws_lambda_invoke.api_handler",
"module": "",
"action": "action.aws_lambda_invoke.api_handler",
"implied_provider": "aws",
"action_type": "aws_lambda_invoke",
"action_name": "api_handler",
"action_key": null
},
"action_trigger": {}
},
"type": "planned_action_invocation"
}
예시: 수명주기 트리거를 통해 호출된 작업
{
"@level":"info",
"@message":"planned action invocation: action.aws_lambda_invoke.api_handler",
"@module":"terraform.ui",
"@timestamp":"2026-07-30T15:23:15.862206+01:00",
"invocation":{
"action_addr":{
"addr":"action.aws_lambda_invoke.api_handler",
"module":"",
"action":"action.aws_lambda_invoke.api_handler",
"implied_provider":"aws",
"action_type":"aws_lambda_invoke",
"action_name":"api_handler",
"action_key":null
},
"lifecycle_trigger":{
"triggering_resource":{
"addr":"aws_lambda_function.api_handler",
"module":"",
"resource":"aws_lambda_function.api_handler",
"implied_provider":"aws",
"resource_type":"aws_lambda_function",
"resource_name":"api_handler",
"resource_key":null
},
"triggering_event":"AfterUpdate",
"action_trigger_block_index":0,
"actions_list_index":0,
"on_failure":"ActionOnFailureHalt"
}
},
"type":"planned_action_invocation"
}
Refresh 시작
refresh_start 메시지 hook 객체는 다음 키를 가져요:
resource: 리소스를 식별하는resource객체id_key및id_value: 리소스의 이 인스턴스를 식별하는 데 사용하는 키/값 쌍
예시
{
"@level": "info",
"@message": "null_resource.none[0]: Refreshing state... [id=1971614370559474622]",
"@module": "terraform.ui",
"@timestamp": "2021-03-26T14:18:06.508915-04:00",
"hook": {
"resource": {
"addr": "null_resource.none[0]",
"module": "",
"resource": "null_resource.none[0]",
"implied_provider": "null",
"resource_type": "null_resource",
"resource_name": "none",
"resource_key": 0
},
"id_key": "id",
"id_value": "1971614370559474622"
},
"type": "refresh_start"
}
Refresh 완료
refresh_complete 메시지 hook 객체는 다음 키를 가져요:
resource: 리소스를 식별하는resource객체id_key및id_value: 리소스의 이 인스턴스를 식별하는 데 사용하는 키/값 쌍
예시
{
"@level": "info",
"@message": "null_resource.none[0]: Refresh complete [id=1971614370559474622]",
"@module": "terraform.ui",
"@timestamp": "2021-03-26T14:18:06.509371-04:00",
"hook": {
"resource": {
"addr": "null_resource.none[0]",
"module": "",
"resource": "null_resource.none[0]",
"implied_provider": "null",
"resource_type": "null_resource",
"resource_name": "none",
"resource_key": 0
},
"id_key": "id",
"id_value": "1971614370559474622"
},
"type": "refresh_complete"
}
임시 작업 시작
ephemeral_op_start 메시지 hook 객체는 다음 키를 가져요:
resource: 리소스를 식별하는resource객체action: 임시 리소스가 겪고 있는 작업. 값:open,renew,close
예시
{
"@level": "info",
"@message": "ephemeral.random_password.example: Opening...",
"@module": "terraform.ui",
"@timestamp": "2024-10-30T10:34:26.222465-00:00",
"hook": {
"resource": {
"addr": "ephemeral.random_password.example",
"module": "",
"resource": "ephemeral.random_password.example",
"implied_provider": "random",
"resource_type": "random_password",
"resource_name": "example",
"resource_key": null
},
"action": "open"
},
"type": "ephemeral_op_start"
}
임시 작업 진행 상황
ephemeral_op_progress 메시지 hook 객체는 다음 키를 가져요:
resource: 리소스를 식별하는resource객체action: 임시 리소스가 겪고 있는 작업. 값:open,renew,closeelapsed_seconds: 작업이 시작된 후 경과한 시간. 정수 초로 표현
예시
{
"@level": "info",
"@message": "ephemeral.random_password.example: Closing... [3s elapsed]",
"@module": "terraform.ui",
"@timestamp": "2024-10-30T10:34:26.222465-00:00",
"hook": {
"resource": {
"addr": "ephemeral.random_password.example",
"module": "",
"resource": "ephemeral.random_password.example",
"implied_provider": "random",
"resource_type": "random_password",
"resource_name": "example",
"resource_key": null
},
"action": "close",
"elapsed_seconds": 3
},
"type": "ephemeral_op_progress"
}
임시 작업 완료
ephemeral_op_complete 메시지 hook 객체는 다음 키를 가져요:
resource: 리소스를 식별하는resource객체action: 임시 리소스가 겪고 있는 작업. 값:open,renew,closeelapsed_seconds: 작업이 시작된 후 경과한 시간. 정수 초로 표현
예시
{
"@level": "info",
"@message": "ephemeral.random_password.example: Opening complete after 1s",
"@module": "terraform.ui",
"@timestamp": "2024-10-30T10:34:26.222465-00:00",
"hook": {
"resource": {
"addr": "ephemeral.random_password.example",
"module": "",
"resource": "ephemeral.random_password.example",
"implied_provider": "random",
"resource_type": "random_password",
"resource_name": "example",
"resource_key": null
},
"action": "open",
"elapsed_seconds": 1
},
"type": "ephemeral_op_complete"
}
임시 작업 오류
ephemeral_op_errored 메시지 hook 객체는 다음 키를 가져요:
resource: 리소스를 식별하는resource객체action: 임시 리소스가 겪고 있는 작업. 값:open,renew,closeelapsed_seconds: 작업이 시작된 후 경과한 시간. 정수 초로 표현
오류의 정확한 세부 정보는 별도의 diagnostic 메시지로 렌더링돼요.
예시
{
"@level": "info",
"@message": "ephemeral.random_password.example: Opening errored after 2s",
"@module": "terraform.ui",
"@timestamp": "2024-10-30T10:34:26.222465-00:00",
"hook": {
"resource": {
"addr": "ephemeral.random_password.example",
"module": "",
"resource": "ephemeral.random_password.example",
"implied_provider": "random",
"resource_type": "random_password",
"resource_name": "example",
"resource_key": null
},
"action": "open",
"elapsed_seconds": 2
},
"type": "ephemeral_op_errored"
}
리소스 객체
resource 객체는 구성의 리소스 주소를 나타내는 분해된 구조로, 주어진 메시지가 어떤 리소스와 연관되는지 식별하는 데 사용돼요. 객체는 다음 키를 가져요:
addr: 문자열로 된 리소스의 전체 고유 주소module: 리소스를 포함하는 모듈의 주소.module.foo.module.bar형식이며, 루트 모듈 리소스의 경우 빈 문자열resource: 모듈 상대 주소. 루트 모듈 리소스의 경우addr와 동일resource_type: 주소가 지정되는 리소스의 유형resource_name: 리소스의 이름 레이블resource_key: 주소 키(count또는for_each값). 둘 다 사용되지 않으면nullimplied_provider: 리소스 유형으로 암시되는 프로바이더 유형. 프로바이더 별칭을 사용하면 리소스의 프로바이더를 반영하지 않을 수 있음
예시
{
"addr": "module.pets.random_pet.pet[\"friend\"]",
"module": "module.pets",
"resource": "random_pet.pet[\"friend\"]",
"implied_provider": "random",
"resource_type": "random_pet",
"resource_name": "pet",
"resource_key": "friend"
}
테스트 개요
terraform test 명령은 임박한 작업 중 Terraform이 실행하는 테스트 파일과 run 블록을 설명하는 test_abstract 메시지를 발행해요.
예시
{
"@level": "info",
"@message": "Found 1 file and 2 run blocks",
"@module": "terraform.ui",
"@timestamp": "2023-08-09T16:12:30.325582+02:00",
"test_abstract": {
"validation.tftest.hcl": [
"passed_validation",
"failed_validatation"
]
},
"type": "test_abstract"
}
테스트 파일
terraform test 실행 내내 Terraform은 각 테스트 파일에 대한 여러 진행 상황 업데이트를 생성해요. 진행 필드는 starting, teardown 또는 complete일 수 있어요. 각 테스트 파일은 각 진행 업데이트를 정확히 한 번 발행해요. 테스트 파일이 complete 진행 업데이트를 발행할 때는 완료된 테스트 파일의 전체 상태를 나타내는 pass, error, fail 또는 skip 중 하나를 포함한 상태 필드도 포함해요.
예시
{
"@level": "info",
"@message": "main.tftest.hcl... pass",
"@module": "terraform.ui",
"@testfile": "validation.tftest.hcl",
"@timestamp": "2023-08-09T16:12:30.724368+02:00",
"test_file": {
"path": "validation.tftest.hcl",
"progress": "complete",
"status": "pass"
},
"type": "test_file"
}
테스트 실행
테스트 파일 내에서 run 블록을 실행하는 동안 Terraform은 각 run 블록에 대한 여러 상태 업데이트도 생성해요. run 블록 진행 업데이트의 진행 필드는 starting, running, teardown, complete일 수 있어요. starting과 complete 진행 업데이트는 정확히 한 번 발행돼요. running과 teardown 진행 업데이트는 여러 번 발행될 수 있어요.
starting, running, teardown 업데이트는 현재 테스트 작업(starting 및 running의 경우) 또는 현재 destroy 작업(teardown의 경우)이 진행 중인 시간을 밀리초로 나타내는 elapsed 필드도 포함해요.
complete 진행 업데이트는 완료된 run 블록의 전체 상태를 나타내는 pass, error, fail 또는 skip 중 하나를 포함한 status 필드도 포함해요.
모든 run 블록이 teardown 진행 업데이트를 발행하는 것은 아니에요. 가장 최근에 실행된 run 블록만 정리되어야 하는 최신 인메모리 상태 파일을 참조하기 때문이에요. 또한 run 블록 정리 프로세스는 전체 테스트 파일이 이미 teardown 상태 업데이트를 발행한 후에만 시작돼요. 이는 teardown 업데이트가 제공되기 전에 run 블록에 대한 complete 진행 업데이트가 발행될 것으로 기대할 수 있다는 뜻이에요. 모든 run 블록의 정리 프로세스가 완료되면 둘러싸는 테스트 파일이 항상 complete 진행 업데이트를 발행해요.
예시
{
"@level": "info",
"@message": " \"successful_validation\"... pass",
"@module": "terraform.ui",
"@testfile": "validation.tftest.hcl",
"@testrun": "successful_validation",
"@timestamp": "2023-08-09T16:12:30.724407+02:00",
"test_run": {
"path": "main.tftest.hcl",
"run": "successful_validation",
"progress": "complete",
"status": "pass"
},
"type": "test_run"
}
{
"@level": "info",
"@message": " \"successful_validation\"... in progress",
"@module": "terraform.ui",
"@testfile": "validation.tftest.hcl",
"@testrun": "successful_validation",
"@timestamp": "2023-08-09T16:12:30.724407+02:00",
"test_run": {
"path": "main.tftest.hcl",
"run": "successful_validation",
"progress": "running",
"elapsed": 2024
},
"type": "test_run"
}
테스트 정리
Terraform이 각 테스트 파일의 실행을 완료한 후, terraform test는 파괴할 수 없었던 상태를 설명하는 일련의 test_cleanup 메시지를 발행할 수 있어요. 이 메시지에 나열된 리소스를 직접 찾아 파괴해야 해요.
테스트 프레임워크는 각 테스트 파일에 대해 여러 상태 파일을 관리할 수 있으므로, Terraform이 파괴할 수 없었던 리소스를 가진 각 상태 파일에 대해 이 메시지의 여러 버전을 볼 수 있어요. @testrun 필드를 사용해 상태 파일을 마지막으로 업데이트한 run 블록을 정확히 찾아 Terraform이 파괴할 수 없었던 리소스를 찾을 수 있어요.
예시
{
"@level": "info",
"@message": "Terraform left some resources in state after executing main.tftest.hcl, they need to be cleaned up manually.",
"@module": "terraform.ui",
"@testfile": "validation.tftest.hcl",
"@testrun": "successful_validation",
"@timestamp": "2023-08-09T16:12:30.724407+02:00",
"test_cleanup": {
"failed_resources": [
{
"instance": "aws_instance.primary"
},
{
"instance": "aws_instance.secondary"
}
]
},
"type": "test_cleanup"
}
테스트 요약
테스트 작업이 모든 테스트 파일을 완료한 후 terraform test는 전체 테스트 작업의 상태와 함께 test_summary 메시지를 발행해요.
예시
{
"@level": "info",
"@message": "Success! 2 passed, 0 failed.",
"@module": "terraform.ui",
"@timestamp": "2023-08-09T16:26:45.482070+02:00",
"test_summary": {
"status": "pass",
"passed": 2,
"failed": 0,
"errored": 0,
"skipped": 0
},
"type": "test_summary"
}
테스트 계획
-verbose 모드에서 terraform test는 plan 작업을 실행한 모든 run 블록에 대해 test_plan 메시지를 발행해요. test_plan 메시지는 terraform show -json 명령 출력과 terraform providers schema -json 명령 출력의 속성 일부를 포함해요.
메시지는 계획을 나타내는 다음 필드를 포함해요: plan_format_version, output_changes, resource_changes, resource_drift, relevant_attributes. 이들은 JSON 계획 표현 (JSON Plan Representation)의 해당 필드와 일치해요.
메시지는 프로바이더 스키마를 나타내는 다음 필드를 포함해요: provider_format_version, provider_schemas. 이들은 JSON 프로바이더 스키마 표현 (JSON Providers Schema Representation)의 해당 필드와 일치해요.
예시
{
"@level": "info",
"@message": "-verbose flag enabled, printing plan",
"@module": "terraform.ui",
"@testfile": "validation.tftest.hcl",
"@testrun": "successful_validation",
"@timestamp": "2023-08-09T17:10:06.211942+02:00",
"test_plan": {
"plan_format_version": "1.2",
"resource_changes": [
{
"address": "aws_instance.primary",
"mode": "managed",
"type": "aws_instance",
"name": "primary",
"provider_name": "registry.terraform.io/hashicorp/aws",
"change": {
"actions": [
"create"
],
"before": null,
"after": {
"ami": "af84f887-e3eb-9e52-5f8b-8a2803734fd0"
},
"after_unknown": {},
"before_sensitive": false,
"after_sensitive": {}
}
}
],
"provider_format_version": "1.0",
"provider_schemas": {
"registry.terraform.io/hashicorp/aws": {
"provider": {
"version": 0
},
"resource_schemas": {
"aws_instance": {
"version": 0,
"block": {
"attributes": {
"ami": {
"type": "string",
"description_kind": "plain",
"required": true
}
},
"description_kind": "plain"
}
}
}
}
}
},
"type": "test_plan"
}
테스트 상태
-verbose 모드에서 terraform test는 apply 작업을 실행한 모든 run 블록에 대해 test_state 메시지를 발행해요. test_state 메시지는 terraform show -json 명령 출력과 terraform providers schema -json 명령 출력의 일부를 포함해요.
메시지는 상태를 나타내는 다음 필드를 포함해요: state_format_version, root_module, outputs. 이들은 완전한 JSON 상태 표현에 포함된 JSON 값 표현 (JSON Values Representation)의 해당 필드와 일치해요.
메시지는 프로바이더 스키마를 나타내는 다음 필드를 포함해요: provider_format_version, provider_schemas. 이들은 JSON 프로바이더 스키마 표현의 해당 필드와 일치해요.
예시
{
"@level": "info",
"@message": "-verbose flag enabled, printing state",
"@module": "terraform.ui",
"@testfile": "validation.tftest.hcl",
"@testrun": "successful_validation",
"@timestamp": "2023-08-09T17:18:21.173008+02:00",
"test_state": {
"state_format_version": "1.0",
"root_module": {
"resources": [
{
"address": "aws_instance.primary",
"mode": "managed",
"type": "aws_instance",
"name": "primary",
"provider_name": "registry.terraform.io/hashicorp/aws",
"schema_version": 0,
"values": {
"ami": "af84f887-e3eb-9e52-5f8b-8a2803734fd0"
},
"sensitive_values": {}
}
]
},
"provider_format_version": "1.0",
"provider_schemas": {
"registry.terraform.io/hashicorp/aws": {
"provider": {
"version": 0
},
"resource_schemas": {
"aws_instance": {
"version": 0,
"block": {
"attributes": {
"ami": {
"type": "string",
"description_kind": "plain",
"required": true
}
},
"description_kind": "plain"
}
}
}
}
}
},
"type": "test_state"
}
테스트 중단
terraform test가 방해를 받거나 취소되면 중단된 작업을 설명하는 test_interrupt 메시지를 발행해요. 이 메시지는 종료 전에 Terraform이 파괴할 수 없었던 모든 상태와 Terraform이 생성을 끝내지 못한 남은 리소스를 포함해요.
테스트 정리 (Test Cleanup) 메시지와 마찬가지로 Terraform이 여러 상태 파일을 유지하고 있었을 수 있어요. state 필드는 테스트 구성의 기본 상태에서 리소스를 포함하고, states 필드는 각 run 블록이 만든 리소스에 대한 run 블록 이름 맵을 포함하는데, Terraform이 이를 파괴할 수 없었어요.
마지막으로 planned 필드는 중단된 run 블록이 생성하는 과정에 있던 리소스를 포함하며, @testrun 필드를 사용해 식별할 수 있어요.
예시
{
"@level": "info",
"@message": "-verbose flag enabled, printing state",
"@module": "terraform.ui",
"@testfile": "validation.tftest.hcl",
"@testrun": "successful_validation",
"@timestamp": "2023-08-09T17:18:21.173008+02:00",
"test_interrupt": {
"state": [
{
"instance": "aws_instance.primary"
}
],
"states": {
"unsuccessful_validation": [
{
"instance": "aws_instance.secondary"
}
]
},
"planned": [
"aws_instance.secondary"
]
},
"type": "test_interrupt"
}
목록 시작
terraform query 명령은 Terraform이 실행하려는 각 list 블록에 대해 list_start 메시지를 발행해요.
예시
{
"@level": "info",
"@message": "list.random_pet.pets: Starting query...",
"@module": "terraform.ui",
"@timestamp": "2025-08-29T14:07:26.954999+02:00",
"list_start": {
"address": "list.random_pet.pets",
"resource_type": "random_pet",
"input_config": {"count":5},
"sensitive_attribute_paths": [".count"]
},
"type": "list_start"
}
목록 리소스 발견
terraform query 명령은 list 블록 실행 중 발견된 각 리소스에 대해 list_resource_found를 발행해요.
예시
{
"@level": "info",
"@message": "list.random_pet.pets: Result found",
"@module": "terraform.ui",
"@timestamp": "2025-08-29T14:07:26.955529+02:00",
"list_resource_found": {
"address": "list.random_pet.pets",
"display_name": "This is a charming-beagle",
"identity": {
"id": "charming-beagle",
"legs": 3
},
"identity_version": 0,
"resource_type": "random_pet"
},
"type": "list_resource_found"
}
목록 완료
terraform query 명령은 list 블록의 모든 결과가 발행된 후 list_complete 메시지를 발행해요.
예시
{
"@level": "info",
"@message": "list.random_pet.pets: List complete",
"@module": "terraform.ui",
"@timestamp": "2025-08-29T14:07:26.955538+02:00",
"list_complete": {
"address": "list.random_pet.pets",
"resource_type": "random_pet",
"total": 5
},
"type": "list_complete"
}