기계가 읽을 수 있는 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: 진단 경고 또는 오류 메시지. 형식에 대한 자세한 내용은 the terraform validate 문서를 참조하세요.

초기화 메시지

init 명령의 JSON 출력에서 온 메시지는 typeinit_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"}

일반

백엔드 초기화

프로바이더 설치

모듈 설치

작업 결과

  • 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 메시지로 시작해요. 다음 메시지별 키가 정의돼요:

  • terraform: 이 메시지를 발행한 Terraform 버전
  • ui: 이후 메시지의 의미를 정의하는 기계가 읽을 수 있는 UI 스키마 버전

예시

{
  "@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 작업일 때만 사용됨. 값:

이 메시지는 변경이 계획되게 만든 정확한 변경에 대한 세부 정보는 포함하지 않아요. 그 정보는 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, delete
  • value: 적용된 출력의 경우, 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 작업을 수행하면 종종 여러 메시지가 발행돼요. 메시지 유형은 다음과 같아요:

이러한 각 메시지는 hook 객체를 가지며, 각 유형에 따라 필드가 달라져요. 모든 훅은 작업의 대상인 리소스를 식별하는 resource 객체를 가져요.

Apply 시작

apply_start 메시지 hook 객체는 다음 키를 가져요:

  • resource: 리소스를 식별하는 resource 객체
  • action: 리소스에 대해 취해질 작업. 값: noop, create, read, update, replace, delete
  • id_keyid_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, delete
  • elapsed_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, delete
  • id_keyid_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, delete
  • elapsed_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 객체는 다음 키를 가져요:

예시

{
  "@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 객체는 다음 키를 가져요:

프로비저너에서 받은 각 로그 줄에 대해 하나의 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 객체는 다음 키를 가져요:

예시

{
  "@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 객체는 다음 키를 가져요:

예시

{
  "@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 객체는 다음 키를 가져요:

action_trigger 객체는 빈 객체이며, 작업이 CLI에서 -invoke 플래그로 호출될 때 존재해요.

lifecycle_trigger 객체는 다음 키를 가져요:

예시: 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_keyid_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_keyid_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 객체는 다음 키를 가져요:

예시

{
  "@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 객체는 다음 키를 가져요:

예시

{
  "@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 객체는 다음 키를 가져요:

예시

{
  "@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 객체는 다음 키를 가져요:

오류의 정확한 세부 정보는 별도의 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 값). 둘 다 사용되지 않으면 null
  • implied_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일 수 있어요. startingcomplete 진행 업데이트는 정확히 한 번 발행돼요. runningteardown 진행 업데이트는 여러 번 발행될 수 있어요.

starting, running, teardown 업데이트는 현재 테스트 작업(startingrunning의 경우) 또는 현재 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"
}

더 알아보기 (Learn more)