github.com/hashicorp/terraform-plugin-sdk@v1.17.2/internal/states/statefile/version1.go (about) 1 package statefile 2 3 import ( 4 "encoding/json" 5 "fmt" 6 7 "github.com/hashicorp/terraform-plugin-sdk/internal/tfdiags" 8 ) 9 10 func readStateV1(src []byte) (*File, tfdiags.Diagnostics) { 11 var diags tfdiags.Diagnostics 12 sV1 := &stateV1{} 13 err := json.Unmarshal(src, sV1) 14 if err != nil { 15 diags = diags.Append(jsonUnmarshalDiags(err)) 16 return nil, diags 17 } 18 19 file, prepDiags := prepareStateV1(sV1) 20 diags = diags.Append(prepDiags) 21 return file, diags 22 } 23 24 func prepareStateV1(sV1 *stateV1) (*File, tfdiags.Diagnostics) { 25 var diags tfdiags.Diagnostics 26 sV2, err := upgradeStateV1ToV2(sV1) 27 if err != nil { 28 diags = diags.Append(tfdiags.Sourceless( 29 tfdiags.Error, 30 upgradeFailed, 31 fmt.Sprintf("Error upgrading state file format from version 1 to version 2: %s.", err), 32 )) 33 return nil, diags 34 } 35 36 file, prepDiags := prepareStateV2(sV2) 37 diags = diags.Append(prepDiags) 38 return file, diags 39 } 40 41 // stateV1 is a representation of the legacy JSON state format version 1. 42 // 43 // It is only used to read version 1 JSON files prior to upgrading them to 44 // the current format. 45 type stateV1 struct { 46 // Version is the protocol version. "1" for a StateV1. 47 Version int `json:"version"` 48 49 // Serial is incremented on any operation that modifies 50 // the State file. It is used to detect potentially conflicting 51 // updates. 52 Serial int64 `json:"serial"` 53 54 // Remote is used to track the metadata required to 55 // pull and push state files from a remote storage endpoint. 56 Remote *remoteStateV1 `json:"remote,omitempty"` 57 58 // Modules contains all the modules in a breadth-first order 59 Modules []*moduleStateV1 `json:"modules"` 60 } 61 62 type remoteStateV1 struct { 63 // Type controls the client we use for the remote state 64 Type string `json:"type"` 65 66 // Config is used to store arbitrary configuration that 67 // is type specific 68 Config map[string]string `json:"config"` 69 } 70 71 type moduleStateV1 struct { 72 // Path is the import path from the root module. Modules imports are 73 // always disjoint, so the path represents amodule tree 74 Path []string `json:"path"` 75 76 // Outputs declared by the module and maintained for each module 77 // even though only the root module technically needs to be kept. 78 // This allows operators to inspect values at the boundaries. 79 Outputs map[string]string `json:"outputs"` 80 81 // Resources is a mapping of the logically named resource to 82 // the state of the resource. Each resource may actually have 83 // N instances underneath, although a user only needs to think 84 // about the 1:1 case. 85 Resources map[string]*resourceStateV1 `json:"resources"` 86 87 // Dependencies are a list of things that this module relies on 88 // existing to remain intact. For example: an module may depend 89 // on a VPC ID given by an aws_vpc resource. 90 // 91 // Terraform uses this information to build valid destruction 92 // orders and to warn the user if they're destroying a module that 93 // another resource depends on. 94 // 95 // Things can be put into this list that may not be managed by 96 // Terraform. If Terraform doesn't find a matching ID in the 97 // overall state, then it assumes it isn't managed and doesn't 98 // worry about it. 99 Dependencies []string `json:"depends_on,omitempty"` 100 } 101 102 type resourceStateV1 struct { 103 // This is filled in and managed by Terraform, and is the resource 104 // type itself such as "mycloud_instance". If a resource provider sets 105 // this value, it won't be persisted. 106 Type string `json:"type"` 107 108 // Dependencies are a list of things that this resource relies on 109 // existing to remain intact. For example: an AWS instance might 110 // depend on a subnet (which itself might depend on a VPC, and so 111 // on). 112 // 113 // Terraform uses this information to build valid destruction 114 // orders and to warn the user if they're destroying a resource that 115 // another resource depends on. 116 // 117 // Things can be put into this list that may not be managed by 118 // Terraform. If Terraform doesn't find a matching ID in the 119 // overall state, then it assumes it isn't managed and doesn't 120 // worry about it. 121 Dependencies []string `json:"depends_on,omitempty"` 122 123 // Primary is the current active instance for this resource. 124 // It can be replaced but only after a successful creation. 125 // This is the instances on which providers will act. 126 Primary *instanceStateV1 `json:"primary"` 127 128 // Tainted is used to track any underlying instances that 129 // have been created but are in a bad or unknown state and 130 // need to be cleaned up subsequently. In the 131 // standard case, there is only at most a single instance. 132 // However, in pathological cases, it is possible for the number 133 // of instances to accumulate. 134 Tainted []*instanceStateV1 `json:"tainted,omitempty"` 135 136 // Deposed is used in the mechanics of CreateBeforeDestroy: the existing 137 // Primary is Deposed to get it out of the way for the replacement Primary to 138 // be created by Apply. If the replacement Primary creates successfully, the 139 // Deposed instance is cleaned up. If there were problems creating the 140 // replacement, the instance remains in the Deposed list so it can be 141 // destroyed in a future run. Functionally, Deposed instances are very 142 // similar to Tainted instances in that Terraform is only tracking them in 143 // order to remember to destroy them. 144 Deposed []*instanceStateV1 `json:"deposed,omitempty"` 145 146 // Provider is used when a resource is connected to a provider with an alias. 147 // If this string is empty, the resource is connected to the default provider, 148 // e.g. "aws_instance" goes with the "aws" provider. 149 // If the resource block contained a "provider" key, that value will be set here. 150 Provider string `json:"provider,omitempty"` 151 } 152 153 type instanceStateV1 struct { 154 // A unique ID for this resource. This is opaque to Terraform 155 // and is only meant as a lookup mechanism for the providers. 156 ID string `json:"id"` 157 158 // Attributes are basic information about the resource. Any keys here 159 // are accessible in variable format within Terraform configurations: 160 // ${resourcetype.name.attribute}. 161 Attributes map[string]string `json:"attributes,omitempty"` 162 163 // Meta is a simple K/V map that is persisted to the State but otherwise 164 // ignored by Terraform core. It's meant to be used for accounting by 165 // external client code. 166 Meta map[string]string `json:"meta,omitempty"` 167 }