github.com/eliastor/durgaform@v0.0.0-20220816172711-d0ab2d17673e/website/docs/internals/json-format.mdx (about)

     1  ---
     2  page_title: 'Internals: JSON Output Format'
     3  description: >-
     4    Terraform provides a machine-readable JSON representation of state,
     5    configuration and plan.
     6  ---
     7  
     8  # JSON Output Format
     9  
    10  -> **Note:** This format is available in Terraform 0.12 and later.
    11  
    12  When Terraform plans to make changes, it prints a human-readable summary to the terminal. It can also, when run with `-out=<PATH>`, write a much more detailed binary plan file, which can later be used to apply those changes.
    13  
    14  Since the format of plan files isn't suited for use with external tools (and likely never will be), Terraform can output a machine-readable JSON representation of a plan file's changes. It can also convert state files to the same format, to simplify data loading and provide better long-term compatibility.
    15  
    16  Use `terraform show -json <FILE>` to generate a JSON representation of a plan or state file. See [the `terraform show` documentation](/cli/commands/show) for more details.
    17  
    18  The output includes a `format_version` key, which as of Terraform 1.1.0 has
    19  value `"1.0"`. The semantics of this version are:
    20  
    21  - We will increment the minor version, e.g. `"1.1"`, for backward-compatible
    22    changes or additions. Ignore any object properties with unrecognized names to
    23    remain forward-compatible with future minor versions.
    24  - We will increment the major version, e.g. `"2.0"`, for changes that are not
    25    backward-compatible. Reject any input which reports an unsupported major
    26    version.
    27  
    28  We will introduce new major versions only within the bounds of
    29  [the Terraform 1.0 Compatibility Promises](/language/v1-compatibility-promises).
    30  
    31  ## Format Summary
    32  
    33  The following sections describe the JSON output format by example, using a pseudo-JSON notation.
    34  
    35  Important elements are described with comments, which are prefixed with `//`.
    36  
    37  To avoid excessive repetition, we've split the complete format into several discrete sub-objects, described under separate headers. References wrapped in angle brackets (like `<values-representation>`) are placeholders which, in the real output, would be replaced by an instance of the specified sub-object.
    38  
    39  The JSON output format consists of the following objects and sub-objects:
    40  
    41  - [State Representation](#state-representation) — The complete top-level object returned by `terraform show -json <STATE FILE>`.
    42  - [Plan Representation](#plan-representation) — The complete top-level object returned by `terraform show -json <PLAN FILE>`.
    43  - [Values Representation](#values-representation) — A sub-object of both plan and state output that describes current state or planned state.
    44  - [Configuration Representation](#configuration-representation) — A sub-object of plan output that describes a parsed Terraform configuration.
    45    - [Expression Representation](#expression-representation) — A sub-object of a configuration representation that describes an unevaluated expression.
    46    - [Block Expressions Representation](#block-expressions-representation) — A sub-object of a configuration representation that describes the expressions nested inside a block.
    47  - [Change Representation](#change-representation) — A sub-object of plan output that describes changes to an object.
    48  
    49  ## State Representation
    50  
    51  Because state does not currently have any significant metadata not covered by the common values representation ([described below](#values-representation)), the `<state-representation>` is straightforward:
    52  
    53  ```javascript
    54  {
    55    // "values" is a values representation object derived from the values in the
    56    // state. Because the state is always fully known, this is always complete.
    57    "values": <values-representation>
    58  
    59    "terraform_version": "version.string"
    60  }
    61  ```
    62  
    63  The extra wrapping object here will allow for any extension we may need to add in future versions of this format.
    64  
    65  ## Plan Representation
    66  
    67  A plan consists of a prior state, the configuration that is being applied to that state, and the set of changes Terraform plans to make to achieve that.
    68  
    69  For ease of consumption by callers, the plan representation includes a partial representation of the values in the final state (using a [value representation](#values-representation)), allowing callers to easily analyze the planned outcome using similar code as for analyzing the prior state.
    70  
    71  ```javascript
    72  {
    73    "format_version": "1.0",
    74  
    75    // "prior_state" is a representation of the state that the configuration is
    76    // being applied to, using the state representation described above.
    77    "prior_state":  <state-representation>,
    78  
    79    // "configuration" is a representation of the configuration being applied to the
    80    // prior state, using the configuration representation described above.
    81    "configuration": <configuration-representation>,
    82  
    83    // "planned_values" is a description of what is known so far of the outcome in
    84    // the standard value representation, with any as-yet-unknown values omitted.
    85    "planned_values": <values-representation>,
    86  
    87    // "proposed_unknown" is a representation of the attributes, including any
    88    // potentially-unknown attributes. Each value is replaced with "true" or
    89    // "false" depending on whether it is known in the proposed plan.
    90    "proposed_unknown": <values-representation>,
    91  
    92    // "variables" is a representation of all the variables provided for the given
    93    // plan. This is structured as a map similar to the output map so we can add
    94    // additional fields in later.
    95    "variables": {
    96      "varname": {
    97        "value": "varvalue"
    98      },
    99    },
   100  
   101    // "resource_changes" is a description of the individual change actions that
   102    // Terraform plans to use to move from the prior state to a new state
   103    // matching the configuration.
   104    "resource_changes": [
   105      // Each element of this array describes the action to take
   106      // for one instance object. All resources in the
   107      // configuration are included in this list.
   108      {
   109        // "address" is the full absolute address of the resource instance this
   110        // change applies to, in the same format as addresses in a value
   111        // representation.
   112        "address": "module.child.aws_instance.foo[0]",
   113  
   114        // "previous_address" is the full absolute address of this resource
   115        // instance as it was known after the previous Terraform run.
   116        // Included only if the address has changed, e.g. by handling
   117        // a "moved" block in the configuration.
   118        "previous_address": "module.instances.aws_instance.foo[0]",
   119  
   120        // "module_address", if set, is the module portion of the above address.
   121        // Omitted if the instance is in the root module.
   122        "module_address": "module.child",
   123  
   124        // "mode", "type", "name", and "index" have the same meaning as in a
   125        // value representation.
   126        "mode": "managed",
   127        "type": "aws_instance",
   128        "name": "foo",
   129        "index": 0,
   130  
   131        // "deposed", if set, indicates that this action applies to a "deposed"
   132        // object of the given instance rather than to its "current" object.
   133        // Omitted for changes to the current object. "address" and "deposed"
   134        // together form a unique key across all change objects in a particular
   135        // plan. The value is an opaque key representing the specific deposed
   136        // object.
   137        "deposed": "deadbeef",
   138  
   139        // "change" describes the change that will be made to the indicated
   140        // object. The <change-representation> is detailed in a section below.
   141        "change": <change-representation>,
   142  
   143        // "action_reason" is some optional extra context about why the
   144        // actions given inside "change" were selected. This is the JSON
   145        // equivalent of annotations shown in the normal plan output like
   146        // "is tainted, so must be replaced" as opposed to just "must be
   147        // replaced".
   148        //
   149        // These reason codes are display hints only and the set of possible
   150        // hints may change over time. Users of this must be prepared to
   151        // encounter unrecognized reasons and treat them as unspecified reasons.
   152        //
   153        // The current set of possible values is:
   154        // - "replace_because_tainted": the object in question is marked as
   155        //   "tainted" in the prior state, so Terraform planned to replace it.
   156        // - "replace_because_cannot_update": the provider indicated that one
   157        //   of the requested changes isn't possible without replacing the
   158        //   existing object with a new object.
   159        // - "replace_by_request": the user explicitly called for this object
   160        //   to be replaced as an option when creating the plan, which therefore
   161        //   overrode what would have been a "no-op" or "update" action otherwise.
   162        // - "delete_because_no_resource_config": Terraform found no resource
   163        //   configuration corresponding to this instance.
   164        // - "delete_because_no_module": The resource instance belongs to a
   165        //   module instance that's no longer declared, perhaps due to changing
   166        //   the "count" or "for_each" argument on one of the containing modules.
   167        // - "delete_because_wrong_repetition": The instance key portion of the
   168        //   resource address isn't of a suitable type for the corresponding
   169        //   resource's configured repetition mode (count, for_each, or neither).
   170        // - "delete_because_count_index": The corresponding resource uses count,
   171        //   but the instance key is out of range for the currently-configured
   172        //   count value.
   173        // - "delete_because_each_key": The corresponding resource uses for_each,
   174        //   but the instance key doesn't match any of the keys in the
   175        //   currently-configured for_each value.
   176        // - "read_because_config_unknown": For a data resource, Terraform cannot
   177        //   read the data during the plan phase because of values in the
   178        //   configuration that won't be known until the apply phase.
   179        // - "read_because_dependency_pending": For a data resource, Terraform
   180        //   cannot read the data during the plan phase because the data
   181        //   resource depends on at least one managed resource that also has
   182        //   a pending change in the same plan.
   183        //
   184        // If there is no special reason to note, Terraform will omit this
   185        // property altogether.
   186        action_reason: "replace_because_tainted"
   187      }
   188    ],
   189  
   190    // "resource_drift" is a description of the changes Terraform detected
   191    // when it compared the most recent state to the prior saved state.
   192    "resource_drift": [
   193      {
   194          // "resource_drift" uses the same object structure as
   195          // "resource_changes".
   196      }
   197    ],
   198  
   199    // "relevant_attributes" lists the sources of all values contributing to
   200    // changes in the plan. You can use "relevant_attributes" to filter
   201    // "resource_drift" and determine which external changes may have affected the
   202    // plan result.
   203    "relevant_attributes": [
   204      {
   205        "resource": "aws_instance.foo",
   206        "attribute": "attr",
   207      }
   208    ]
   209  
   210    // "output_changes" describes the planned changes to the output values of the
   211    // root module.
   212    "output_changes": {
   213      // Keys are the defined output value names.
   214      "foo": {
   215  
   216        // "change" describes the change that will be made to the indicated output
   217        // value, using the same representation as for resource changes except
   218        // that the only valid actions values are:
   219        //   ["create"]
   220        //   ["update"]
   221        //   ["delete"]
   222        // In the Terraform CLI 0.12.0 release, Terraform is not yet fully able to
   223        // track changes to output values, so the actions indicated may not be
   224        // fully accurate, but the "after" value will always be correct.
   225        "change": <change-representation>,
   226      }
   227    }
   228  }
   229  ```
   230  
   231  This overall plan structure, fully expanded, is what will be printed by the `terraform show -json <planfile>` command.
   232  
   233  ## Values Representation
   234  
   235  A values representation is used in both state and plan output to describe current state (which is always complete) and planned state (which omits values not known until apply).
   236  
   237  The following example illustrates the structure of a `<values-representation>`:
   238  
   239  ```javascript
   240  {
   241    // "outputs" describes the outputs from the root module. Outputs from
   242    // descendent modules are not available because they are not retained in all
   243    // of the underlying structures we will build this values representation from.
   244    "outputs": {
   245      "private_ip": {
   246        "value": "192.168.3.2",
   247        "type": "string",
   248        "sensitive": false
   249      }
   250    },
   251  
   252    // "root_module" describes the resources and child modules in the root module.
   253    "root_module": {
   254      "resources": [
   255        {
   256          // "address" is the absolute resource address, which callers must consider
   257          // opaque but may do full string comparisons with other address strings or
   258          // pass this verbatim to other Terraform commands that are documented to
   259          // accept absolute resource addresses. The module-local portions of this
   260          // address are extracted in other properties below.
   261          "address": "aws_instance.example[1]",
   262  
   263          // "mode" can be "managed", for resources, or "data", for data resources
   264          "mode": "managed",
   265          "type": "aws_instance",
   266          "name": "example",
   267  
   268          // If the count or for_each meta-arguments are set for this resource, the
   269          // additional key "index" is present to give the instance index key. This
   270          // is omitted for the single instance of a resource that isn't using count
   271          // or for_each.
   272          "index": 1,
   273  
   274          // "provider_name" is the name of the provider that is responsible for
   275          // this resource. This is only the provider name, not a provider
   276          // configuration address, and so no module path nor alias will be
   277          // indicated here. This is included to allow the property "type" to be
   278          // interpreted unambiguously in the unusual situation where a provider
   279          // offers a resource type whose name does not start with its own name,
   280          // such as the "googlebeta" provider offering "google_compute_instance".
   281          "provider_name": "aws",
   282  
   283          // "schema_version" indicates which version of the resource type schema
   284          // the "values" property conforms to.
   285          "schema_version": 2,
   286  
   287          // "values" is the JSON representation of the attribute values of the
   288          // resource, whose structure depends on the resource type schema. Any
   289          // unknown values are omitted or set to null, making them
   290          // indistinguishable from absent values; callers which need to distinguish
   291          // unknown from unset must use the plan-specific or configuration-specific
   292          // structures described in later sections.
   293          "values": {
   294            "id": "i-abc123",
   295            "instance_type": "t2.micro",
   296            // etc, etc
   297          },
   298  
   299          // "sensitive_values" is the JSON representation of the sensitivity of
   300          // the resource's attribute values. Only attributes which are sensitive
   301          // are included in this structure.
   302          "sensitive_values": {
   303            "id": true,
   304          }
   305        }
   306      ]
   307  
   308      "child_modules": [
   309        // Each entry in "child_modules" has the same structure as the root_module
   310        // object, with the additional "address" property shown below.
   311        {
   312          // "address" is the absolute module address, which callers must treat as
   313          // opaque but may do full string comparisons with other module address
   314          // strings and may pass verbatim to other Terraform commands that are
   315          // documented as accepting absolute module addresses.
   316          "address": "module.child",
   317  
   318          // "resources" is the same as in "root_module" above
   319          "resources": [
   320              {
   321                "address": "module.child.aws_instance.foo",
   322                // etc, etc
   323              }
   324          ],
   325  
   326          // Each module object can optionally have its own
   327          // nested "child_modules", recursively describing the
   328          // full module tree.
   329          "child_modules": [ ... ],
   330        }
   331      ]
   332    }
   333  }
   334  ```
   335  
   336  The translation of attribute and output values is the same intuitive mapping from HCL types to JSON types used by Terraform's [`jsonencode`](/language/functions/jsonencode) function. This mapping does lose some information: lists, sets, and tuples all lower to JSON arrays while maps and objects both lower to JSON objects. Unknown values and null values are both treated as absent or null.
   337  
   338  Output values include a `"type"` field, which is a [serialization of the value's type](https://pkg.go.dev/github.com/zclconf/go-cty/cty#Type.MarshalJSON). For primitive types this is a string value, such as `"number"` or `"bool"`. Complex types are represented as a nested JSON array, such as `["map","string"]` or `["object",{"a":"number"}]`. This can be used to reconstruct the output value with the correct type.
   339  
   340  Only the "current" object for each resource instance is described. "Deposed" objects are not reflected in this structure at all; in plan representations, you can refer to the change representations for further details.
   341  
   342  The intent of this structure is to give a caller access to a similar level of detail as is available to expressions within the configuration itself. This common representation is not suitable for all use-cases because it loses information compared to the data structures it is built from. For more complex needs, use the more elaborate changes and configuration representations.
   343  
   344  ## Configuration Representation
   345  
   346  Configuration is the most complicated structure in Terraform, since it includes unevaluated expression nodes and other complexities.
   347  
   348  Because the configuration models are produced at a stage prior to expression evaluation, it is not possible to produce a values representation for configuration. Instead, we describe the physical structure of the configuration, giving access to constant values where possible and allowing callers to analyze any references to other objects that are present:
   349  
   350  ```javascript
   351  {
   352    // "provider_configs" describes all of the provider configurations throughout
   353    // the configuration tree, flattened into a single map for convenience since
   354    // provider configurations are the one concept in Terraform that can span
   355    // across module boundaries.
   356    "provider_config": {
   357  
   358      // Keys in the provider_configs map are to be considered opaque by callers,
   359      // and used just for lookups using the "provider_config_key" property in each
   360      // resource object.
   361      "opaque_provider_ref_aws": {
   362  
   363        // "name" is the name of the provider without any alias
   364        "name": "aws",
   365  
   366        // "full_name" is the fully-qualified provider name
   367        "full_name": "registry.terraform.io/hashicorp/aws",
   368  
   369        // "alias" is the alias set for a non-default configuration, or unset for
   370        // a default configuration.
   371        "alias": "foo",
   372  
   373        // "module_address" is included only for provider configurations that are
   374        // declared in a descendent module, and gives the opaque address for the
   375        // module that contains the provider configuration.
   376        "module_address": "module.child",
   377  
   378        // "expressions" describes the provider-specific content of the
   379        // configuration block, as a block expressions representation (see section
   380        // below).
   381        "expressions": <block-expressions-representation>
   382      }
   383    },
   384  
   385    // "root_module" describes the root module in the configuration, and serves
   386    // as the root of a tree of similar objects describing descendent modules.
   387    "root_module": {
   388  
   389      // "outputs" describes the output value configurations in the module.
   390      "outputs": {
   391  
   392        // Property names here are the output value names
   393        "example": {
   394          "expression": <expression-representation>,
   395          "sensitive": false
   396        }
   397      },
   398  
   399      // "resources" describes the "resource" and "data" blocks in the module
   400      // configuration.
   401      "resources": [
   402        {
   403          // "address" is the opaque absolute address for the resource itself.
   404          "address": "aws_instance.example",
   405  
   406          // "mode", "type", and "name" have the same meaning as for the resource
   407          // portion of a value representation.
   408          "mode": "managed",
   409          "type": "aws_instance",
   410          "name": "example",
   411  
   412          // "provider_config_key" is the key into "provider_configs" (shown
   413          // above) for the provider configuration that this resource is
   414          // associated with. If the provider configuration was passed into
   415          // this module from the parent module, the key will point to the
   416          // original provider config block.
   417          "provider_config_key": "opaque_provider_ref_aws",
   418  
   419          // "provisioners" is an optional field which describes any provisioners.
   420          // Connection info will not be included here.
   421          "provisioners": [
   422            {
   423              "type": "local-exec",
   424  
   425              // "expressions" describes the provisioner configuration
   426              "expressions": <block-expressions-representation>
   427            },
   428          ],
   429  
   430          // "expressions" describes the resource-type-specific content of the
   431          // configuration block.
   432          "expressions": <block-expressions-representation>,
   433  
   434          // "schema_version" is the schema version number indicated by the
   435          // provider for the type-specific arguments described in "expressions".
   436          "schema_version": 2,
   437  
   438          // "count_expression" and "for_each_expression" describe the expressions
   439          // given for the corresponding meta-arguments in the resource
   440          // configuration block. These are omitted if the corresponding argument
   441          // isn't set.
   442          "count_expression": <expression-representation>,
   443          "for_each_expression": <expression-representation>
   444        },
   445      ],
   446  
   447      // "module_calls" describes the "module" blocks in the module. During
   448      // evaluation, a module call with count or for_each may expand to multiple
   449      // module instances, but in configuration only the block itself is
   450      // represented.
   451      "module_calls": {
   452  
   453        // Key is the module call name chosen in the configuration.
   454        "child": {
   455  
   456          // "resolved_source" is the resolved source address of the module, after
   457          // any normalization and expansion. This could be either a
   458          // go-getter-style source address or a local path starting with "./" or
   459          // "../". If the user gave a registry source address then this is the
   460          // final location of the module as returned by the registry, after
   461          // following any redirect indirection.
   462          "resolved_source": "./child"
   463  
   464          // "expressions" describes the expressions for the arguments within the
   465          // block that correspond to input variables in the child module.
   466          "expressions": <block-expressions-representation>,
   467  
   468          // "count_expression" and "for_each_expression" describe the expressions
   469          // given for the corresponding meta-arguments in the module
   470          // configuration block. These are omitted if the corresponding argument
   471          // isn't set.
   472          "count_expression": <expression-representation>,
   473          "for_each_expression": <expression-representation>,
   474  
   475          // "module" is a representation of the configuration of the child module
   476          // itself, using the same structure as the "root_module" object,
   477          // recursively describing the full module tree.
   478          "module": <module-configuration-representation>
   479        }
   480      }
   481    }
   482  }
   483  ```
   484  
   485  ### Expression Representation
   486  
   487  Each unevaluated expression in the configuration is represented with an `<expression-representation>` object with the following structure:
   488  
   489  ```javascript
   490  {
   491    // "constant_value" is set only if the expression contains no references to
   492    // other objects, in which case it gives the resulting constant value. This is
   493    // mapped as for the individual values in a value representation.
   494    "constant_value": "hello",
   495  
   496    // Alternatively, "references" will be set to a list of references in the
   497    // expression. Multi-step references will be unwrapped and duplicated for each
   498    // significant traversal step, allowing callers to more easily recognize the
   499    // objects they care about without attempting to parse the expressions.
   500    // Callers should only use string equality checks here, since the syntax may
   501    // be extended in future releases.
   502    "references": [
   503      "data.template_file.foo[1].vars[\"baz\"]",
   504      "data.template_file.foo[1].vars", // implied by previous
   505      "data.template_file.foo[1]", // implied by previous
   506      "data.template_file.foo", // implied by previous
   507      "module.foo.bar",
   508      "module.foo", // implied by the previous
   509      "var.example[0]",
   510      "var.example", // implied by the previous
   511  
   512      // Partial references like "data" and "module" are not included, because
   513      // Terraform considers "module.foo" to be an atomic reference, not an
   514      // attribute access.
   515    ]
   516  }
   517  ```
   518  
   519  -> **Note:** Expressions in `dynamic` blocks are not included in the configuration representation.
   520  
   521  ### Block Expressions Representation
   522  
   523  In some cases, it is the entire content of a block (possibly after certain special arguments have already been handled and removed) that must be represented. For that, we have an `<block-expressions-representation>` structure:
   524  
   525  ```javascript
   526  {
   527    // Attribute arguments are mapped directly with the attribute name as key and
   528    // an <expression-representation> as value.
   529    "ami": <expression-representation>,
   530    "instance_type": <expression-representation>,
   531  
   532    // Nested block arguments are mapped as either a single nested
   533    // <block-expressions-representation> or an array object of these, depending on the
   534    // block nesting mode chosen in the schema.
   535    //  - "single" nesting is a direct <block-expressions-representation>
   536    //  - "list" and "set" produce arrays
   537    //  - "map" produces an object
   538    "root_block_device": <expression-representation>,
   539    "ebs_block_device": [
   540      <expression-representation>
   541    ]
   542  }
   543  ```
   544  
   545  For now we expect callers to just hard-code assumptions about the schemas of particular resource types in order to process these expression representations. In a later release we will add new inspection commands to return machine-readable descriptions of the schemas themselves, allowing for more generic handling in programs such as visualization tools.
   546  
   547  ## Change Representation
   548  
   549  A `<change-representation>` describes the change to the indicated object.
   550  
   551  ```javascript
   552  {
   553    // "actions" are the actions that will be taken on the object selected by the
   554    // properties below.
   555    // Valid actions values are:
   556    //    ["no-op"]
   557    //    ["create"]
   558    //    ["read"]
   559    //    ["update"]
   560    //    ["delete", "create"]
   561    //    ["create", "delete"]
   562    //    ["delete"]
   563    // The two "replace" actions are represented in this way to allow callers to
   564    // e.g. just scan the list for "delete" to recognize all three situations
   565    // where the object will be deleted, allowing for any new deletion
   566    // combinations that might be added in future.
   567    "actions": ["update"],
   568  
   569    // "before" and "after" are representations of the object value both before
   570    // and after the action. For ["create"] and ["delete"] actions, either
   571    // "before" or "after" is unset (respectively). For ["no-op"], the before and
   572    // after values are identical. The "after" value will be incomplete if there
   573    // are values within it that won't be known until after apply.
   574    "before": <value-representation>,
   575    "after": <value-representation>,
   576  
   577    // "after_unknown" is an object value with similar structure to "after", but
   578    // with all unknown leaf values replaced with "true", and all known leaf
   579    // values omitted. This can be combined with "after" to reconstruct a full
   580    // value after the action, including values which will only be known after
   581    // apply.
   582    "after_unknown": {
   583      "id": true
   584    },
   585  
   586    // "before_sensitive" and "after_sensitive" are object values with similar
   587    // structure to "before" and "after", but with all sensitive leaf values
   588    // replaced with true, and all non-sensitive leaf values omitted. These
   589    // objects should be combined with "before" and "after" to prevent accidental
   590    // display of sensitive values in user interfaces.
   591    "before_sensitive": {},
   592    "after_sensitive": {
   593      "triggers": {
   594        "boop": true
   595      }
   596    },
   597  
   598    // "replace_paths" is an array of arrays representing a set of paths into the
   599    // object value which resulted in the action being "replace". This will be
   600    // omitted if the action is not replace, or if no paths caused the
   601    // replacement (for example, if the resource was tainted). Each path
   602    // consists of one or more steps, each of which will be a number or a
   603    // string.
   604    "replace_paths": [["triggers"]]
   605  }
   606  ```