github.com/cycloidio/terraform@v1.1.10-0.20220513142504-76d5c768dc63/docs/resource-instance-change-lifecycle.md (about)

     1  # Terraform Resource Instance Change Lifecycle
     2  
     3  This document describes the relationships between the different operations
     4  called on a Terraform Provider to handle a change to a resource instance.
     5  
     6  ![](https://gist.githubusercontent.com/apparentlymart/c4e401cdb724fa5b866850c78569b241/raw/fefa90ce625c240d5323ea28c92943c2917e36e3/resource_instance_change_lifecycle.png)
     7  
     8  The process includes several different artifacts that are all objects
     9  conforming to the schema of the resource type in question, representing
    10  different subsets of the instance for different purposes:
    11  
    12  * **Configuration**: Contains only values from the configuration, including
    13    unknown values in any case where the argument value is derived from an
    14    unknown result on another resource. Any attributes not set directly in the
    15    configuration are null.
    16  
    17  * **Prior State**: The full object produced by a previous apply operation, or
    18    null if the instance is being created for the first time.
    19  
    20  * **Proposed New State**: Terraform Core merges the non-null values from
    21    the configuration with any computed attribute results in the prior state
    22    to produce a combined object that includes both, to avoid each provider
    23    having to re-implement that merging logic. Will be null when planning a
    24    delete operation.
    25  
    26  * **Planned New State**: An approximation of the result the provider expects
    27    to produce when applying the requested change. This is usually derived from
    28    the proposed new state by inserting default attribute values in place of
    29    null values and overriding any computed attribute values that are expected
    30    to change as a result of the apply operation. May include unknown values
    31    for attributes whose results cannot be predicted until apply. Will be null
    32    when planning a delete operation.
    33  
    34  * **New State**: The actual result of applying the change, with any unknown
    35    values from the planned new state replaced with final result values. This
    36    value will be used as the input to plan the next operation.
    37  
    38  The remaining sections describe the three provider API functions that are
    39  called to plan and apply a change, including the expectations Terraform Core
    40  enforces for each.
    41  
    42  For historical reasons, the original Terraform SDK is exempt from error
    43  messages produced when the assumptions are violated, but violating them will
    44  often cause downstream errors nonetheless, because Terraform's workflow
    45  depends on these contracts being met.
    46  
    47  The following section uses the word "attribute" to refer to the named
    48  attributes described in the resource type schema. A schema may also include
    49  nested blocks, which contain their _own_ set of attributes; the constraints
    50  apply recursively to these nested attributes too.
    51  
    52  Nested blocks are a configuration-only construct and so the number of blocks
    53  cannot be changed on the fly during planning or during apply: each block
    54  represented in the configuration must have a corresponding nested object in
    55  the planned new state and new state, or an error will be returned.
    56  
    57  If a provider wishes to report about new instances of the sub-object type
    58  represented by nested blocks that are created implicitly during the apply
    59  operation -- for example, if a compute instance gets a default network
    60  interface created when none are explicitly specified -- this must be done via
    61  separate `Computed` attributes alongside the nested blocks, which could for
    62  example be a list or map of objects that includes a mixture of the objects
    63  described by the nested blocks in the configuration and any additional objects
    64  created by the remote system.
    65  
    66  ## ValidateResourceTypeConfig
    67  
    68  `ValidateResourceTypeConfig` is the provider's opportunity to perform any
    69  custom validation of the configuration that cannot be represented in the schema
    70  alone.
    71  
    72  In principle the provider can require any constraint it sees fit here, though
    73  in practice it should avoid reporting errors when values are unknown (so that
    74  the operation can proceed and determine those values downstream) and if
    75  it intends to apply default values during `PlanResourceChange` then it must
    76  tolerate those attributes being null at validation time, because validation
    77  happens before planning.
    78  
    79  A provider should repeat similar validation logic at the start of
    80  `PlanResourceChange`, in order to catch any new
    81  values that have switched from unknown to known along the way during the
    82  overall plan/apply flow.
    83  
    84  ## PlanResourceChange
    85  
    86  The purpose of `PlanResourceChange` is to predict the approximate effect of
    87  a subsequent apply operation, allowing Terraform to render the plan for the
    88  user and to propagate any predictable results downstream through expressions
    89  in the configuration.
    90  
    91  The _planned new state_ returned from the provider must meet the following
    92  constraints:
    93  
    94  * Any attribute that was non-null in the configuration must either preserve
    95    the exact configuration value or return the corresponding attribute value
    96    from the prior state. (Do the latter if you determine that the change is not
    97    functionally significant, such as if the value is a JSON string that has
    98    changed only in the positioning of whitespace.)
    99  
   100  * Any attribute that is marked as computed in the schema _and_ is null in the
   101    configuration may be set by the provider to any arbitrary value of the
   102    expected type.
   103  
   104  * If a computed attribute has any _known_ value in the planned new state, the
   105    provider will be required to ensure that it is unchanged in the new state
   106    returned by `ApplyResourceChange`, or return an error explaining why it
   107    changed. Set an attribute to an unknown value to indicate that its final
   108    result will be determined during `ApplyResourceChange`.
   109  
   110  `PlanResourceChange` is actually called twice for each resource type.
   111  It will be called first during the planning phase before Terraform prints out
   112  the diff to the user for confirmation. If the user accepts the plan, then
   113  `PlanResourceChange` will be called _again_ during the apply phase with any
   114  unknown values from configuration filled in with their final results from
   115  upstream resources. The second planned new state is compared with the first
   116  and must meet the following additional constraints along with those listed
   117  above:
   118  
   119  * Any attribute that had a known value in the first planned new state must
   120    have an identical value in the second.
   121  
   122  * Any attribute that had an unknown value in the first planned new state may
   123    either remain unknown in the second or take on any known value of the
   124    expected type.
   125  
   126  It is the second planned new state that is finally provided to
   127  `ApplyResourceChange`, as described in the following section.
   128  
   129  ## ApplyResourceChange
   130  
   131  The `ApplyResourceChange` function is responsible for making calls into the
   132  remote system to make remote objects match the planned new state. During that
   133  operation, it should determine final values for any attributes that were left
   134  unknown in the planned new state, thus producing a wholly-known _new state_
   135  object.
   136  
   137  `ApplyResourceChange` also receives the prior state so that it can use it
   138  to potentially implement more "surgical" changes to particular parts of
   139  the remote objects by detecting portions that are unchanged, in cases where the
   140  remote API supports partial-update operations.
   141  
   142  The new state object returned from the provider must meet the following
   143  constraints:
   144  
   145  * Any attribute that had a known value in the planned new state must have an
   146    identical value in the new state.
   147  
   148  * Any attribute that had an unknown value in the planned new state must take
   149    on a known value of the expected type in the new state. No unknown values
   150    are allowed in the new state.