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