github.com/muratcelep/terraform@v1.1.0-beta2-not-internal-4/website/docs/internals/machine-readable-ui.html.md (about)

     1  ---
     2  layout: "docs"
     3  page_title: "Internals: Machine-Readable UI"
     4  sidebar_current: "docs-internals-machine-readable-ui"
     5  description: |-
     6    Terraform provides a machine-readable streaming JSON UI output for plan, apply, and refresh operations.
     7  ---
     8  
     9  # Machine-Readable UI
    10  
    11  -> **Note:** This format is available in Terraform 0.15.3 and later.
    12  
    13  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.
    14  
    15  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.
    16  
    17  The first message output has type `version`, and includes a `ui` key, which as of Terraform 1.1.0 has
    18  value `"1.0"`. The semantics of this version are:
    19  
    20  - We will increment the minor version, e.g. `"1.1"`, for backward-compatible
    21    changes or additions. Ignore any object properties with unrecognized names to
    22    remain forward-compatible with future minor versions.
    23  - We will increment the major version, e.g. `"2.0"`, for changes that are not
    24    backward-compatible. Reject any input which reports an unsupported major
    25    version.
    26  
    27  We will introduce new major versions only within the bounds of
    28  [the Terraform 1.0 Compatibility Promises](https://www.terraform.io/docs/language/v1-compatibility-promises.html).
    29  
    30  ## Sample JSON Output
    31  
    32  Below is sample output from running `terraform apply -json`:
    33  
    34  ```javascript
    35  {"@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"}
    36  {"@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"}
    37  {"@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"}
    38  {"@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"}
    39  {"@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"}
    40  {"@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"}
    41  {"@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"}
    42  ```
    43  
    44  Each line consists of a JSON object with several keys common to all messages. These are:
    45  
    46  - `@level`: this is normally "info", but can be "error" or "warn" when showing diagnostics
    47  - `@message`: a human-readable summary of the contents of this message
    48  - `@module`: always "terraform.ui" when rendering UI output
    49  - `@timestamp`: an RFC3339 timestamp of when the message was output
    50  - `type`: defines which kind of message this is and determines how to interpret other keys which may be present
    51  
    52  Clients presenting the logs as a user interface should handle unexpected message types by presenting at least the `@message` field to the user.
    53  
    54  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](#resource-object) can be used to link multiple messages about a single resource.
    55  
    56  ## Message Types
    57  
    58  The following message types are supported:
    59  
    60  ### Generic Messages
    61  
    62  - `version`: information about the Terraform version and the version of the schema used for the following messages
    63  - `log`: unstructured human-readable log lines
    64  - `diagnostic`: diagnostic warning or error messages; [see the `terraform validate` docs for more details on the format](/docs/cli/commands/validate.html#json)
    65  
    66  ### Operation Results
    67  
    68  - `resource_drift`: describes a detected change to a single resource made outside of Terraform
    69  - `planned_change`: describes a planned change to a single resource
    70  - `change_summary`: summary of all planned or applied changes
    71  - `outputs`: list of all root module outputs
    72  
    73  ### Resource Progress
    74  
    75  - `apply_start`, `apply_progress`, `apply_complete`, `apply_errored`: sequence of messages indicating progress of a single resource through apply
    76  - `provision_start`, `provision_progress`, `provision_complete`, `provision_errored`: sequence of messages indicating progress of a single provisioner step
    77  - `refresh_start`, `refresh_complete`: sequence of messages indicating progress of a single resource through refresh
    78  
    79  ## Version Message
    80  
    81  A machine-readable UI command output will always begin with a `version` message. The following message-specific keys are defined:
    82  
    83  - `terraform`: the Terraform version which emitted this message
    84  - `ui`: the machine-readable UI schema version defining the meaning of the following messages
    85  
    86  ### Example
    87  
    88  ```json
    89  {
    90    "@level": "info",
    91    "@message": "Terraform 0.15.4",
    92    "@module": "terraform.ui",
    93    "@timestamp": "2021-05-25T13:32:41.275359-04:00",
    94    "terraform": "0.15.4",
    95    "type": "version",
    96    "ui": "0.1.0"
    97  }
    98  ```
    99  
   100  ## Resource Drift
   101  
   102  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:
   103  
   104  - `resource`: object describing the address of the resource to be changed; see [resource object](#resource-object) below for details
   105  - `action`: the action planned to be taken for the resource. Values: `update`, `delete`.
   106  
   107  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](./json-format.html).
   108  
   109  ### Example
   110  
   111  ```json
   112  {
   113    "@level": "info",
   114    "@message": "random_pet.animal: Drift detected (update)",
   115    "@module": "terraform.ui",
   116    "@timestamp": "2021-05-25T13:32:41.705503-04:00",
   117    "change": {
   118      "resource": {
   119        "addr": "random_pet.animal",
   120        "module": "",
   121        "resource": "random_pet.animal",
   122        "implied_provider": "random",
   123        "resource_type": "random_pet",
   124        "resource_name": "animal",
   125        "resource_key": null
   126      },
   127      "action": "update"
   128    },
   129    "type": "resource_drift"
   130  }
   131  ```
   132  
   133  ## Planned Change
   134  
   135  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:
   136  
   137  - `resource`: object describing the address of the resource to be changed; see [resource object](#resource-object) below for details
   138  - `previous_resource`: object describing the previous address of the resource, if this change includes a configuration-driven move
   139  - `action`: the action planned to be taken for the resource. Values: `noop`, `create`, `read`, `update`, `replace`, `delete`, `move`.
   140  - `reason`: an optional reason for the change, currently only used when the action is `replace` or `delete`. Values:
   141      - `tainted`: resource was marked as tainted
   142      - `requested`: user requested that the resource be replaced, for example via the `-replace` plan flag
   143      - `cannot_update`: changes to configuration force the resource to be deleted and created rather than updated
   144      - `delete_because_no_resource_config`: no matching resource in configuration
   145      - `delete_because_wrong_repetition`: resource instance key has no corresponding `count` or `for_each` in configuration
   146      - `delete_because_count_index`: resource instance key is outside the range of the `count` argument
   147      - `delete_because_each_key`: resource instance key is not included in the `for_each` argument
   148      - `delete_because_no_module`: enclosing module instance is not in configuration
   149  
   150  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](./json-format.html).
   151  
   152  ### Example
   153  
   154  ```json
   155  {
   156    "@level": "info",
   157    "@message": "random_pet.animal: Plan to create",
   158    "@module": "terraform.ui",
   159    "@timestamp": "2021-05-25T13:32:41.705503-04:00",
   160    "change": {
   161      "resource": {
   162        "addr": "random_pet.animal",
   163        "module": "",
   164        "resource": "random_pet.animal",
   165        "implied_provider": "random",
   166        "resource_type": "random_pet",
   167        "resource_name": "animal",
   168        "resource_key": null
   169      },
   170      "action": "create"
   171    },
   172    "type": "planned_change"
   173  }
   174  ```
   175  
   176  ## Change Summary
   177  
   178  Terraform outputs a change summary when a plan or apply operation completes. Both message types include a `changes` object, which has the following keys:
   179  
   180  - `add`: count of resources to be created (including as part of replacement)
   181  - `change`: count of resources to be changed in-place
   182  - `remove`: count of resources to be destroyed (including as part of replacement)
   183  - `operation`: one of `plan`, `apply`, or `destroy`
   184  
   185  ### Example
   186  
   187  ```json
   188  {
   189    "@level": "info",
   190    "@message": "Apply complete! Resources: 1 added, 0 changed, 0 destroyed.",
   191    "@module": "terraform.ui",
   192    "@timestamp": "2021-05-25T13:32:41.869168-04:00",
   193    "changes": {
   194      "add": 1,
   195      "change": 0,
   196      "remove": 0,
   197      "operation": "apply"
   198    },
   199    "type": "change_summary"
   200  }
   201  ```
   202  
   203  ## Outputs
   204  
   205  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:
   206  
   207  - `action`: for planned outputs, the action which will be taken for the output. Values: `noop`, `create`, `update`, `delete`
   208  - `value`: for applied outputs, the value of the output, encoded in JSON
   209  - `type`: for applied outputs, the detected HCL type of the output value
   210  - `sensitive`: boolean value, `true` if the output is sensitive and should be hidden from UI by default
   211  
   212  Note that `sensitive` outputs still include the `value` field, and integrating software should respect the sensitivity value as appropriate for the given use case.
   213  
   214  ### Example
   215  
   216  ```json
   217  {
   218    "@level": "info",
   219    "@message": "Outputs: 1",
   220    "@module": "terraform.ui",
   221    "@timestamp": "2021-05-25T13:32:41.869280-04:00",
   222    "outputs": {
   223      "pets": {
   224        "sensitive": false,
   225        "type": "string",
   226        "value": "smart-lizard"
   227      }
   228    },
   229    "type": "outputs"
   230  }
   231  ```
   232  
   233  ## Operation Messages
   234  
   235  Performing Terraform operations to a resource will often result in several messages being emitted. The message types include:
   236  
   237  - `apply_start`: when starting to apply changes for a resource
   238  - `apply_progress`: periodically, showing elapsed time output
   239  - `apply_complete`: on successful operation completion
   240  - `apply_errored`: when an error is encountered during the operation
   241  - `provision_start`: when starting a provisioner step
   242  - `provision_progress`: on provisioner output
   243  - `provision_complete`: on successful provisioning
   244  - `provision_errored`: when an error is enountered during provisioning
   245  - `refresh_start`: when reading a resource during refresh
   246  - `refresh_complete`: on successful refresh
   247  
   248  Each of these messages has a `hook` object, which has different fields for each type. All hooks have a [`resource` object](#resource-object) which identifies which resource is the subject of the operation.
   249  
   250  ## Apply Start
   251  
   252  The `apply_start` message `hook` object has the following keys:
   253  
   254  - `resource`: a [`resource` object](#resource-object) identifying the resource
   255  - `action`: the action to be taken for the resource. Values: `noop`, `create`, `read`, `update`, `replace`, `delete`
   256  - `id_key` and `id_value`: a key/value pair used to identify this instance of the resource, omitted when unknown
   257  
   258  ### Example
   259  
   260  ```json
   261  {
   262    "@level": "info",
   263    "@message": "random_pet.animal: Creating...",
   264    "@module": "terraform.ui",
   265    "@timestamp": "2021-05-25T13:32:41.825308-04:00",
   266    "hook": {
   267      "resource": {
   268        "addr": "random_pet.animal",
   269        "module": "",
   270        "resource": "random_pet.animal",
   271        "implied_provider": "random",
   272        "resource_type": "random_pet",
   273        "resource_name": "animal",
   274        "resource_key": null
   275      },
   276      "action": "create"
   277    },
   278    "type": "apply_start"
   279  }
   280  ```
   281  
   282  ## Apply Progress
   283  
   284  The `apply_progress` message `hook` object has the following keys:
   285  
   286  - `resource`: a [`resource` object](#resource-object) identifying the resource
   287  - `action`: the action being taken for the resource. Values: `noop`, `create`, `read`, `update`, `replace`, `delete`
   288  - `elapsed_seconds`: time elapsed since the apply operation started, expressed as an integer number of seconds
   289  
   290  ### Example
   291  
   292  ```json
   293  {
   294    "@level": "info",
   295    "@message": "null_resource.none[4]: Still creating... [30s elapsed]",
   296    "@module": "terraform.ui",
   297    "@timestamp": "2021-03-17T09:34:26.222465-04:00",
   298    "hook": {
   299      "resource": {
   300        "addr": "null_resource.none[4]",
   301        "module": "",
   302        "resource": "null_resource.none[4]",
   303        "implied_provider": "null",
   304        "resource_type": "null_resource",
   305        "resource_name": "none",
   306        "resource_key": 4
   307      },
   308      "action": "create",
   309      "elapsed_seconds": 30
   310    },
   311    "type": "apply_progress"
   312  }
   313  ```
   314  
   315  ## Apply Complete
   316  
   317  The `apply_complete` message `hook` object has the following keys:
   318  
   319  - `resource`: a [`resource` object](#resource-object) identifying the resource
   320  - `action`: the action taken for the resource. Values: `noop`, `create`, `read`, `update`, `replace`, `delete`
   321  - `id_key` and `id_value`: a key/value pair used to identify this instance of the resource, omitted when unknown
   322  - `elapsed_seconds`: time elapsed since the apply operation started, expressed as an integer number of seconds
   323  
   324  ### Example
   325  
   326  ```json
   327  {
   328    "@level": "info",
   329    "@message": "random_pet.animal: Creation complete after 0s [id=smart-lizard]",
   330    "@module": "terraform.ui",
   331    "@timestamp": "2021-05-25T13:32:41.826179-04:00",
   332    "hook": {
   333      "resource": {
   334        "addr": "random_pet.animal",
   335        "module": "",
   336        "resource": "random_pet.animal",
   337        "implied_provider": "random",
   338        "resource_type": "random_pet",
   339        "resource_name": "animal",
   340        "resource_key": null
   341      },
   342      "action": "create",
   343      "id_key": "id",
   344      "id_value": "smart-lizard",
   345      "elapsed_seconds": 0
   346    },
   347    "type": "apply_complete"
   348  }
   349  ```
   350  
   351  ## Apply Errored
   352  
   353  The `apply_complete` message `hook` object has the following keys:
   354  
   355  - `resource`: a [`resource` object](#resource-object) identifying the resource
   356  - `action`: the action taken for the resource. Values: `noop`, `create`, `read`, `update`, `replace`, `delete`
   357  - `elapsed_seconds`: time elapsed since the apply operation started, expressed as an integer number of seconds
   358  
   359  The exact detail of the error will be rendered as a separate `diagnostic` message.
   360  
   361  ### Example
   362  
   363  ```json
   364  {
   365    "@level": "info",
   366    "@message": "null_resource.none[0]: Creation errored after 10s",
   367    "@module": "terraform.ui",
   368    "@timestamp": "2021-03-26T16:38:54.013910-04:00",
   369    "hook": {
   370      "resource": {
   371        "addr": "null_resource.none[0]",
   372        "module": "",
   373        "resource": "null_resource.none[0]",
   374        "implied_provider": "null",
   375        "resource_type": "null_resource",
   376        "resource_name": "none",
   377        "resource_key": 0
   378      },
   379      "action": "create",
   380      "elapsed_seconds": 10
   381    },
   382    "type": "apply_errored"
   383  }
   384  ```
   385  
   386  ## Provision Start
   387  
   388  The `provision_start` message `hook` object has the following keys:
   389  
   390  - `resource`: a [`resource` object](#resource-object) identifying the resource
   391  - `provisioner`: the type of provisioner
   392  
   393  ### Example
   394  
   395  ```json
   396  {
   397    "@level": "info",
   398    "@message": "null_resource.none[0]: Provisioning with 'local-exec'...",
   399    "@module": "terraform.ui",
   400    "@timestamp": "2021-03-26T16:38:43.997431-04:00",
   401    "hook": {
   402      "resource": {
   403        "addr": "null_resource.none[0]",
   404        "module": "",
   405        "resource": "null_resource.none[0]",
   406        "implied_provider": "null",
   407        "resource_type": "null_resource",
   408        "resource_name": "none",
   409        "resource_key": 0
   410      },
   411      "provisioner": "local-exec"
   412    },
   413    "type": "provision_start"
   414  }
   415  ```
   416  
   417  ## Provision Progress
   418  
   419  The `provision_progress` message `hook` object has the following keys:
   420  
   421  - `resource`: a [`resource` object](#resource-object) identifying the resource
   422  - `provisioner`: the type of provisioner
   423  - `output`: the output log from the provisioner
   424  
   425  One `provision_progress` message is output for each log line received from the provisioner.
   426  
   427  ### Example
   428  
   429  ```json
   430  {
   431    "@level": "info",
   432    "@message": "null_resource.none[0]: (local-exec): Executing: [\"/bin/sh\" \"-c\" \"sleep 10 && exit 1\"]",
   433    "@module": "terraform.ui",
   434    "@timestamp": "2021-03-26T16:38:43.997869-04:00",
   435    "hook": {
   436      "resource": {
   437        "addr": "null_resource.none[0]",
   438        "module": "",
   439        "resource": "null_resource.none[0]",
   440        "implied_provider": "null",
   441        "resource_type": "null_resource",
   442        "resource_name": "none",
   443        "resource_key": 0
   444      },
   445      "provisioner": "local-exec",
   446      "output": "Executing: [\"/bin/sh\" \"-c\" \"sleep 10 && exit 1\"]"
   447    },
   448    "type": "provision_progress"
   449  }
   450  ```
   451  
   452  ## Provision Complete
   453  
   454  The `provision_complete` message `hook` object has the following keys:
   455  
   456  - `resource`: a [`resource` object](#resource-object) identifying the resource
   457  - `provisioner`: the type of provisioner
   458  
   459  ### Example
   460  
   461  ```json
   462  {
   463    "@level": "info",
   464    "@message": "null_resource.none[0]: (local-exec) Provisioning complete",
   465    "@module": "terraform.ui",
   466    "@timestamp": "2021-03-17T09:34:06.239043-04:00",
   467    "hook": {
   468      "resource": {
   469        "addr": "null_resource.none[0]",
   470        "module": "",
   471        "resource": "null_resource.none[0]",
   472        "implied_provider": "null",
   473        "resource_type": "null_resource",
   474        "resource_name": "none",
   475        "resource_key": 0
   476      },
   477      "provisioner": "local-exec"
   478    },
   479    "type": "provision_complete"
   480  }
   481  ```
   482  
   483  ## Provision Errored
   484  
   485  The `provision_errored` message `hook` object has the following keys:
   486  
   487  - `resource`: a [`resource` object](#resource-object) identifying the resource
   488  - `provisioner`: the type of provisioner
   489  
   490  ### Example
   491  
   492  ```json
   493  {
   494    "@level": "info",
   495    "@message": "null_resource.none[0]: (local-exec) Provisioning errored",
   496    "@module": "terraform.ui",
   497    "@timestamp": "2021-03-26T16:38:54.013572-04:00",
   498    "hook": {
   499      "resource": {
   500        "addr": "null_resource.none[0]",
   501        "module": "",
   502        "resource": "null_resource.none[0]",
   503        "implied_provider": "null",
   504        "resource_type": "null_resource",
   505        "resource_name": "none",
   506        "resource_key": 0
   507      },
   508      "provisioner": "local-exec"
   509    },
   510    "type": "provision_errored"
   511  }
   512  ```
   513  
   514  ## Refresh Start
   515  
   516  The `refresh_start` message `hook` object has the following keys:
   517  
   518  - `resource`: a [`resource` object](#resource-object) identifying the resource
   519  - `id_key` and `id_value`: a key/value pair used to identify this instance of the resource
   520  
   521  ### Example
   522  
   523  ```json
   524  {
   525    "@level": "info",
   526    "@message": "null_resource.none[0]: Refreshing state... [id=1971614370559474622]",
   527    "@module": "terraform.ui",
   528    "@timestamp": "2021-03-26T14:18:06.508915-04:00",
   529    "hook": {
   530      "resource": {
   531        "addr": "null_resource.none[0]",
   532        "module": "",
   533        "resource": "null_resource.none[0]",
   534        "implied_provider": "null",
   535        "resource_type": "null_resource",
   536        "resource_name": "none",
   537        "resource_key": 0
   538      },
   539      "id_key": "id",
   540      "id_value": "1971614370559474622"
   541    },
   542    "type": "refresh_start"
   543  }
   544  ```
   545  
   546  ## Refresh Complete
   547  
   548  The `refresh_complete` message `hook` object has the following keys:
   549  
   550  - `resource`: a [`resource` object](#resource-object) identifying the resource
   551  - `id_key` and `id_value`: a key/value pair used to identify this instance of the resource
   552  
   553  ### Example
   554  
   555  ```json
   556  {
   557    "@level": "info",
   558    "@message": "null_resource.none[0]: Refresh complete [id=1971614370559474622]",
   559    "@module": "terraform.ui",
   560    "@timestamp": "2021-03-26T14:18:06.509371-04:00",
   561    "hook": {
   562      "resource": {
   563        "addr": "null_resource.none[0]",
   564        "module": "",
   565        "resource": "null_resource.none[0]",
   566        "implied_provider": "null",
   567        "resource_type": "null_resource",
   568        "resource_name": "none",
   569        "resource_key": 0
   570      },
   571      "id_key": "id",
   572      "id_value": "1971614370559474622"
   573    },
   574    "type": "refresh_complete"
   575  }
   576  ```
   577  
   578  ## Resource Object
   579  
   580  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:
   581  
   582  - `addr`: the full unique address of the resource as a string
   583  - `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
   584  - `resource`: the module-relative address, which is identical to `addr` for root module resources
   585  - `resource_type`: the type of resource being addressed
   586  - `resource_name`: the name label for the resource
   587  - `resource_key`: the address key (`count` or `for_each` value), or `null` if the neither are used
   588  - `implied_provider`: the provider type implied by the resource type; this may not reflect the resource's provider if provider aliases are used
   589  
   590  ### Example
   591  
   592  ```json
   593  {
   594    "addr": "module.pets.random_pet.pet[\"friend\"]",
   595    "module": "module.pets",
   596    "resource": "random_pet.pet[\"friend\"]",
   597    "implied_provider": "random",
   598    "resource_type": "random_pet",
   599    "resource_name": "pet",
   600    "resource_key": "friend"
   601  }
   602  ```