» Machine Readable UI

By default, many Terraform commands display UI output as unstructured text, intended to be read by a user via a terminal emulator. This text stream is not a stable interface for integrations. Some commands support a -json flag, which enables a structured JSON output mode with a defined interface.

For long-running commands such as plan, apply, and refresh, the -json flag outputs a stream of JSON UI messages, one per line. These can be processed one message at a time, with integrating software filtering, combining, or modifying the output as desired.

» Sample JSON Output

Below is sample output from running 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"}

Each line consists of a JSON object with several keys common to all messages. These are:

  • @level: this is normally "info", but can be "error" or "warn" when showing diagnostics
  • @message: a human-readable summary of the contents of this message
  • @module: always "terraform.ui" when rendering UI output
  • @timestamp: an RFC3339 timestamp of when the message was output
  • type: defines which kind of message this is and determines how to interpret other keys which may be present

Clients presenting the logs as a user interface should handle unexpected message types by presenting at least the @message field to the user.

Messages will be emitted as events occur to trigger them. This means that messages related to several resources may be interleaved (if Terraform is running with concurrency above 1). The resource object value can be used to link multiple messages about a single resource.

» Message Types

The following message types are supported:

» Generic Messages

» Operation Results

  • resource_drift: describes a detected change to a single resource made outside of Terraform
  • planned_change: describes a planned change to a single resource
  • change_summary: summary of all planned or applied changes
  • outputs: list of all root module outputs

» Resource Progress

  • apply_start, apply_progress, apply_complete, apply_errored: sequence of messages indicating progress of a single resource through apply
  • provision_start, provision_progress, provision_complete, provision_errored: sequence of messages indicating progress of a single provisioner step
  • refresh_start, refresh_complete: sequence of messages indicating progress of a single resource through refresh

» Version Message

A machine-readable UI command output will always begin with a version message. The following message-specific keys are defined:

  • terraform: the Terraform version which emitted this message
  • ui: the machine-readable UI schema version defining the meaning of the following messages

» Example

{
  "@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"
}

» Resource Drift

If drift is detected during planning, Terraform will emit a resource_drift message for each resource which has changed outside of Terraform. This message has an embedded change object with the following keys:

  • resource: object describing the address of the resource to be changed; see resource object below for details
  • action: the action planned to be taken for the resource. Values: update, delete.

This message does not include details about the exact changes which caused the change to be planned. That information is available in the JSON plan output.

» Example

{
  "@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"
}

» Planned Change

At the end of a plan or before an apply, Terraform will emit a planned_change message for each resource which has changes to apply. This message has an embedded change object with the following keys:

  • resource: object describing the address of the resource to be changed; see resource object below for details
  • action: the action planned to be taken for the resource. Values: noop, create, read, update, replace, delete.
  • reason: an optional reason for the change, currently only used when the action is replace. Values:
    • tainted: resource was marked as tainted
    • requested: user requested that the resource be replaced, for example via the -replace plan flag
    • cannot_update: changes to configuration force the resource to be deleted and created rather than updated

This message does not include details about the exact changes which caused the change to be planned. That information is available in the JSON plan output.

» Example

{
  "@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"
}

» Change Summary

Terraform outputs a change summary when a plan or apply operation completes. Both message types include a changes object, which has the following keys:

  • add: count of resources to be created (including as part of replacement)
  • change: count of resources to be changed in-place
  • remove: count of resources to be destroyed (including as part of replacement)
  • operation: one of plan, apply, or destroy

» Example

{
  "@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"
}

» Outputs

After a successful plan or apply, a message with type outputs contains the values of all root module output values. This message contains an outputs object, the keys of which are the output names. The outputs values are objects with the following keys:

  • action: for planned outputs, the action which will be taken for the output. Values: noop, create, update, delete
  • value: for applied outputs, the value of the output, encoded in JSON
  • type: for applied outputs, the detected HCL type of the output value
  • sensitive: boolean value, true if the output is sensitive and should be hidden from UI by default

Note that sensitive outputs still include the value field, and integrating software should respect the sensitivity value as appropriate for the given use case.

» Example

{
  "@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"
}

» Operation Messages

Performing Terraform operations to a resource will often result in several messages being emitted. The message types include:

Each of these messages has a hook object, which has different fields for each type. All hooks have a resource object which identifies which resource is the subject of the operation.

» Apply Start

The apply_start message hook object has the following keys:

  • resource: a resource object identifying the resource
  • action: the action to be taken for the resource. Values: noop, create, read, update, replace, delete
  • id_key and id_value: a key/value pair used to identify this instance of the resource, omitted when unknown

» Example

{
  "@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 Progress

The apply_progress message hook object has the following keys:

  • resource: a resource object identifying the resource
  • action: the action being taken for the resource. Values: noop, create, read, update, replace, delete
  • elapsed_seconds: time elapsed since the apply operation started, expressed as an integer number of seconds

» Example

{
  "@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 Complete

The apply_complete message hook object has the following keys:

  • resource: a resource object identifying the resource
  • action: the action taken for the resource. Values: noop, create, read, update, replace, delete
  • id_key and id_value: a key/value pair used to identify this instance of the resource, omitted when unknown
  • elapsed_seconds: time elapsed since the apply operation started, expressed as an integer number of seconds

» Example

{
  "@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 Errored

The apply_complete message hook object has the following keys:

  • resource: a resource object identifying the resource
  • action: the action taken for the resource. Values: noop, create, read, update, replace, delete
  • elapsed_seconds: time elapsed since the apply operation started, expressed as an integer number of seconds

The exact detail of the error will be rendered as a separate diagnostic message.

» Example

{
  "@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 Start

The provision_start message hook object has the following keys:

» Example

{
  "@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 Progress

The provision_progress message hook object has the following keys:

One provision_progress message is output for each log line received from the provisioner.

» Example

{
  "@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 Complete

The provision_complete message hook object has the following keys:

» Example

{
  "@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 Errored

The provision_errored message hook object has the following keys:

» Example

{
  "@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"
}

» Refresh Start

The refresh_start message hook object has the following keys:

» Example

{
  "@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 Complete

The refresh_complete message hook object has the following keys:

» Example

{
  "@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"
}

» Resource Object

The resource object is a decomposed structure representing a resource address in configuration, which is used to identify which resource a given message is associated with. The object has the following keys:

  • addr: the full unique address of the resource as a string
  • module: the address of the module containing the resource, in the form module.foo.module.bar, or an empty string for a root module resource
  • resource: the module-relative address, which is identical to addr for root module resources
  • resource_type: the type of resource being addressed
  • resource_name: the name label for the resource
  • resource_key: the address key (count or for_each value), or null if the neither are used
  • implied_provider: the provider type implied by the resource type; this may not reflect the resource's provider if provider aliases are used

» Example

{
  "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"
}