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  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.