18 "github.com/hashicorp/go-multierror"
19 "github.com/hashicorp/go-version"
20 "github.com/hashicorp/terraform/config"
21 "github.com/mitchellh/copystructure"
22 "github.com/satori/go.uuid"
26 // StateVersion is the current version for our state file
30 // rootModulePath is the path of the root module
31 var rootModulePath = []string{"root"}
33 // normalizeModulePath takes a raw module path and returns a path that
34 // has the rootModulePath prepended to it. If I could go back in time I
35 // would've never had a rootModulePath (empty path would be root). We can
36 // still fix this but thats a big refactor that my branch doesn't make sense
37 // for. Instead, this function normalizes paths.
38 func normalizeModulePath(p []string) []string {
39 k := len(rootModulePath)
41 // If we already have a root module prefix, we're done
42 if len(p) >= len(rootModulePath) {
43 if reflect.DeepEqual(p[:k], rootModulePath) {
49 result := make([]string, len(rootModulePath)+len(p))
50 copy(result, rootModulePath)
55 // State keeps track of a snapshot state-of-the-world that Terraform
56 // can use to keep track of what real world resources it is actually
59 // Version is the state file protocol version.
60 Version int `json:"version"`
62 // TFVersion is the version of Terraform that wrote this state.
63 TFVersion string `json:"terraform_version,omitempty"`
65 // Serial is incremented on any operation that modifies
66 // the State file. It is used to detect potentially conflicting
68 Serial int64 `json:"serial"`
70 // Lineage is set when a new, blank state is created and then
71 // never updated. This allows us to determine whether the serials
72 // of two states can be meaningfully compared.
73 // Apart from the guarantee that collisions between two lineages
74 // are very unlikely, this value is opaque and external callers
75 // should only compare lineage strings byte-for-byte for equality.
76 Lineage string `json:"lineage"`
78 // Remote is used to track the metadata required to
79 // pull and push state files from a remote storage endpoint.
80 Remote *RemoteState `json:"remote,omitempty"`
82 // Backend tracks the configuration for the backend in use with
83 // this state. This is used to track any changes in the backend
85 Backend *BackendState `json:"backend,omitempty"`
87 // Modules contains all the modules in a breadth-first order
88 Modules []*ModuleState `json:"modules"`
93 func (s *State) Lock() { s.mu.Lock() }
94 func (s *State) Unlock() { s.mu.Unlock() }
96 // NewState is used to initialize a blank state
97 func NewState() *State {
103 // Children returns the ModuleStates that are direct children of
104 // the given path. If the path is "root", for example, then children
105 // returned might be "root.child", but not "root.child.grandchild".
106 func (s *State) Children(path []string) []*ModuleState {
111 return s.children(path)
114 func (s *State) children(path []string) []*ModuleState {
115 result := make([]*ModuleState, 0)
116 for _, m := range s.Modules {
121 if len(m.Path) != len(path)+1 {
124 if !reflect.DeepEqual(path, m.Path[:len(path)]) {
128 result = append(result, m)
134 // AddModule adds the module with the given path to the state.
136 // This should be the preferred method to add module states since it
137 // allows us to optimize lookups later as well as control sorting.
138 func (s *State) AddModule(path []string) *ModuleState {
142 return s.addModule(path)
145 func (s *State) addModule(path []string) *ModuleState {
146 // check if the module exists first
147 m := s.moduleByPath(path)
152 m = &ModuleState{Path: path}
154 s.Modules = append(s.Modules, m)
159 // ModuleByPath is used to lookup the module state for the given path.
160 // This should be the preferred lookup mechanism as it allows for future
161 // lookup optimizations.
162 func (s *State) ModuleByPath(path []string) *ModuleState {
169 return s.moduleByPath(path)
172 func (s *State) moduleByPath(path []string) *ModuleState {
173 for _, mod := range s.Modules {
178 panic("missing module path")
180 if reflect.DeepEqual(mod.Path, path) {
187 // ModuleOrphans returns all the module orphans in this state by
188 // returning their full paths. These paths can be used with ModuleByPath
189 // to return the actual state.
190 func (s *State) ModuleOrphans(path []string, c *config.Config) [][]string {
194 return s.moduleOrphans(path, c)
198 func (s *State) moduleOrphans(path []string, c *config.Config) [][]string {
199 // direct keeps track of what direct children we have both in our config
200 // and in our state. childrenKeys keeps track of what isn't an orphan.
201 direct := make(map[string]struct{})
202 childrenKeys := make(map[string]struct{})
204 for _, m := range c.Modules {
205 childrenKeys[m.Name] = struct{}{}
206 direct[m.Name] = struct{}{}
210 // Go over the direct children and find any that aren't in our keys.
211 var orphans [][]string
212 for _, m := range s.children(path) {
213 key := m.Path[len(m.Path)-1]
215 // Record that we found this key as a direct child. We use this
216 // later to find orphan nested modules.
217 direct[key] = struct{}{}
219 // If we have a direct child still in our config, it is not an orphan
220 if _, ok := childrenKeys[key]; ok {
224 orphans = append(orphans, m.Path)
227 // Find the orphans that are nested...
228 for _, m := range s.Modules {
233 // We only want modules that are at least grandchildren
234 if len(m.Path) < len(path)+2 {
238 // If it isn't part of our tree, continue
239 if !reflect.DeepEqual(path, m.Path[:len(path)]) {
243 // If we have the direct child, then just skip it.
244 key := m.Path[len(path)]
245 if _, ok := direct[key]; ok {
249 orphanPath := m.Path[:len(path)+1]
251 // Don't double-add if we've already added this orphan (which can happen if
252 // there are multiple nested sub-modules that get orphaned together).
253 alreadyAdded := false
254 for _, o := range orphans {
255 if reflect.DeepEqual(o, orphanPath) {
265 orphans = append(orphans, orphanPath)
271 // Empty returns true if the state is empty.
272 func (s *State) Empty() bool {
279 return len(s.Modules) == 0
282 // HasResources returns true if the state contains any resources.
284 // This is similar to !s.Empty, but returns true also in the case where the
285 // state has modules but all of them are devoid of resources.
286 func (s *State) HasResources() bool {
291 for _, mod := range s.Modules {
292 if len(mod.Resources) > 0 {
300 // IsRemote returns true if State represents a state that exists and is
302 func (s *State) IsRemote() bool {
312 if s.Remote.Type == "" {
319 // Validate validates the integrity of this state file.
321 // Certain properties of the statefile are expected by Terraform in order
322 // to behave properly. The core of Terraform will assume that once it
323 // receives a State structure that it has been validated. This validation
324 // check should be called to ensure that.
326 // If this returns an error, then the user should be notified. The error
327 // response will include detailed information on the nature of the error.
328 func (s *State) Validate() error {
334 // !!!! FOR DEVELOPERS !!!!
336 // Any errors returned from this Validate function will BLOCK TERRAFORM
337 // from loading a state file. Therefore, this should only contain checks
338 // that are only resolvable through manual intervention.
340 // !!!! FOR DEVELOPERS !!!!
342 // Make sure there are no duplicate module states. We open a new
343 // block here so we can use basic variable names and future validations
346 found := make(map[string]struct{})
347 for _, ms := range s.Modules {
352 key := strings.Join(ms.Path, ".")
353 if _, ok := found[key]; ok {
354 result = multierror.Append(result, fmt.Errorf(
355 strings.TrimSpace(stateValidateErrMultiModule), key))
359 found[key] = struct{}{}
366 // Remove removes the item in the state at the given address, returning
367 // any errors that may have occurred.
369 // If the address references a module state or resource, it will delete
370 // all children as well. To check what will be deleted, use a StateFilter
372 func (s *State) Remove(addr ...string) error {
376 // Filter out what we need to delete
377 filter := &StateFilter{State: s}
378 results, err := filter.Filter(addr...)
383 // If we have no results, just exit early, we're not going to do anything.
384 // While what happens below is fairly fast, this is an important early
385 // exit since the prune below might modify the state more and we don't
386 // want to modify the state if we don't have to.
387 if len(results) == 0 {
391 // Go through each result and grab what we need
392 removed := make(map[interface{}]struct{})
393 for _, r := range results {
394 // Convert the path to our own type
395 path := append([]string{"root"}, r.Path...)
397 // If we removed this already, then ignore
398 if _, ok := removed[r.Value]; ok {
402 // If we removed the parent already, then ignore
404 if _, ok := removed[r.Parent.Value]; ok {
409 // Add this to the removed list
410 removed[r.Value] = struct{}{}
412 switch v := r.Value.(type) {
414 s.removeModule(path, v)
416 s.removeResource(path, v)
418 s.removeInstance(path, r.Parent.Value.(*ResourceState), v)
420 return fmt.Errorf("unknown type to delete: %T", r.Value)
424 // Prune since the removal functions often do the bare minimum to
425 // remove a thing and may leave around dangling empty modules, resources,
426 // etc. Prune will clean that all up.
432 func (s *State) removeModule(path []string, v *ModuleState) {
433 for i, m := range s.Modules {
435 s.Modules, s.Modules[len(s.Modules)-1] = append(s.Modules[:i], s.Modules[i+1:]...), nil
441 func (s *State) removeResource(path []string, v *ResourceState) {
442 // Get the module this resource lives in. If it doesn't exist, we're done.
443 mod := s.moduleByPath(path)
448 // Find this resource. This is a O(N) lookup when if we had the key
449 // it could be O(1) but even with thousands of resources this shouldn't
450 // matter right now. We can easily up performance here when the time comes.
451 for k, r := range mod.Resources {
454 delete(mod.Resources, k)
460 func (s *State) removeInstance(path []string, r *ResourceState, v *InstanceState) {
461 // Go through the resource and find the instance that matches this
462 // (if any) and remove it.
471 lists := [][]*InstanceState{r.Deposed}
472 for _, is := range lists {
473 for i, instance := range is {
475 // Found it, remove it
476 is, is[len(is)-1] = append(is[:i], is[i+1:]...), nil
485 // RootModule returns the ModuleState for the root module
486 func (s *State) RootModule() *ModuleState {
487 root := s.ModuleByPath(rootModulePath)
489 panic("missing root module")
494 // Equal tests if one state is equal to another.
495 func (s *State) Equal(other *State) bool {
496 // If one is nil, we do a direct check
497 if s == nil || other == nil {
503 return s.equal(other)
506 func (s *State) equal(other *State) bool {
507 if s == nil || other == nil {
511 // If the versions are different, they're certainly not equal
512 if s.Version != other.Version {
516 // If any of the modules are not equal, then this state isn't equal
517 if len(s.Modules) != len(other.Modules) {
520 for _, m := range s.Modules {
521 // This isn't very optimal currently but works.
522 otherM := other.moduleByPath(m.Path)
527 // If they're not equal, then we're not equal!
528 if !m.Equal(otherM) {
536 type StateAgeComparison int
539 StateAgeEqual StateAgeComparison = 0
540 StateAgeReceiverNewer StateAgeComparison = 1
541 StateAgeReceiverOlder StateAgeComparison = -1
544 // CompareAges compares one state with another for which is "older".
546 // This is a simple check using the state's serial, and is thus only as
547 // reliable as the serial itself. In the normal case, only one state
548 // exists for a given combination of lineage/serial, but Terraform
549 // does not guarantee this and so the result of this method should be
552 // Returns an integer that is negative if the receiver is older than
553 // the argument, positive if the converse, and zero if they are equal.
554 // An error is returned if the two states are not of the same lineage,
555 // in which case the integer returned has no meaning.
556 func (s *State) CompareAges(other *State) (StateAgeComparison, error) {
557 // nil states are "older" than actual states
559 case s != nil && other == nil:
560 return StateAgeReceiverNewer, nil
561 case s == nil && other != nil:
562 return StateAgeReceiverOlder, nil
563 case s == nil && other == nil:
564 return StateAgeEqual, nil
567 if !s.SameLineage(other) {
568 return StateAgeEqual, fmt.Errorf(
569 "can't compare two states of differing lineage",
577 case s.Serial < other.Serial:
578 return StateAgeReceiverOlder, nil
579 case s.Serial > other.Serial:
580 return StateAgeReceiverNewer, nil
582 return StateAgeEqual, nil
586 // SameLineage returns true only if the state given in argument belongs
587 // to the same "lineage" of states as the receiver.
588 func (s *State) SameLineage(other *State) bool {
592 // If one of the states has no lineage then it is assumed to predate
593 // this concept, and so we'll accept it as belonging to any lineage
594 // so that a lineage string can be assigned to newer versions
595 // without breaking compatibility with older versions.
596 if s.Lineage == "" || other.Lineage == "" {
600 return s.Lineage == other.Lineage
603 // DeepCopy performs a deep copy of the state structure and returns
605 func (s *State) DeepCopy() *State {
606 copy, err := copystructure.Config{Lock: true}.Copy(s)
614 // IncrementSerialMaybe increments the serial number of this state
615 // if it different from the other state.
616 func (s *State) IncrementSerialMaybe(other *State) {
626 if s.Serial > other.Serial {
629 if other.TFVersion != s.TFVersion || !s.equal(other) {
630 if other.Serial > s.Serial {
631 s.Serial = other.Serial
638 // FromFutureTerraform checks if this state was written by a Terraform
639 // version from the future.
640 func (s *State) FromFutureTerraform() bool {
644 // No TF version means it is certainly from the past
645 if s.TFVersion == "" {
649 v := version.Must(version.NewVersion(s.TFVersion))
650 return SemVersion.LessThan(v)
653 func (s *State) Init() {
659 func (s *State) init() {
661 s.Version = StateVersion
663 if s.moduleByPath(rootModulePath) == nil {
664 s.addModule(rootModulePath)
668 for _, mod := range s.Modules {
680 func (s *State) EnsureHasLineage() {
687 func (s *State) ensureHasLineage() {
689 s.Lineage = uuid.NewV4().String()
690 log.Printf("[DEBUG] New state was assigned lineage %q\n", s.Lineage)
692 log.Printf("[TRACE] Preserving existing state lineage %q\n", s.Lineage)
696 // AddModuleState insert this module state and override any existing ModuleState
697 func (s *State) AddModuleState(mod *ModuleState) {
702 s.addModuleState(mod)
705 func (s *State) addModuleState(mod *ModuleState) {
706 for i, m := range s.Modules {
707 if reflect.DeepEqual(m.Path, mod.Path) {
713 s.Modules = append(s.Modules, mod)
717 // prune is used to remove any resources that are no longer required
718 func (s *State) prune() {
723 // Filter out empty modules.
724 // A module is always assumed to have a path, and it's length isn't always
725 // bounds checked later on. Modules may be "emptied" during destroy, but we
726 // never want to store those in the state.
727 for i := 0; i < len(s.Modules); i++ {
728 if s.Modules[i] == nil || len(s.Modules[i].Path) == 0 {
729 s.Modules = append(s.Modules[:i], s.Modules[i+1:]...)
734 for _, mod := range s.Modules {
737 if s.Remote != nil && s.Remote.Empty() {
742 // sort sorts the modules
743 func (s *State) sort() {
744 sort.Sort(moduleStateSort(s.Modules))
746 // Allow modules to be sorted
747 for _, m := range s.Modules {
754 func (s *State) String() string {
762 for _, m := range s.Modules {
765 // If we're the root module, we just write the output directly.
766 if reflect.DeepEqual(m.Path, rootModulePath) {
767 buf.WriteString(mStr + "\n")
771 buf.WriteString(fmt.Sprintf("module.%s:\n", strings.Join(m.Path[1:], ".")))
773 s := bufio.NewScanner(strings.NewReader(mStr))
780 buf.WriteString(fmt.Sprintf("%s\n", text))
784 return strings.TrimSpace(buf.String())
787 // BackendState stores the configuration to connect to a remote backend.
788 type BackendState struct {
789 Type string `json:"type"` // Backend type
790 Config map[string]interface{} `json:"config"` // Backend raw config
792 // Hash is the hash code to uniquely identify the original source
793 // configuration. We use this to detect when there is a change in
794 // configuration even when "type" isn't changed.
795 Hash uint64 `json:"hash"`
798 // Empty returns true if BackendState has no state.
799 func (s *BackendState) Empty() bool {
800 return s == nil || s.Type == ""
803 // Rehash returns a unique content hash for this backend's configuration
804 // as a uint64 value.
805 // The Hash stored in the backend state needs to match the config itself, but
806 // we need to compare the backend config after it has been combined with all
808 // This function must match the implementation used by config.Backend.
809 func (s *BackendState) Rehash() uint64 {
814 cfg := config.Backend{
816 RawConfig: &config.RawConfig{
824 // RemoteState is used to track the information about a remote
825 // state store that we push/pull state to.
826 type RemoteState struct {
827 // Type controls the client we use for the remote state
828 Type string `json:"type"`
830 // Config is used to store arbitrary configuration that
832 Config map[string]string `json:"config"`
837 func (s *RemoteState) Lock() { s.mu.Lock() }
838 func (s *RemoteState) Unlock() { s.mu.Unlock() }
840 func (r *RemoteState) init() {
845 r.Config = make(map[string]string)
849 func (r *RemoteState) deepcopy() *RemoteState {
853 confCopy := make(map[string]string, len(r.Config))
854 for k, v := range r.Config {
863 func (r *RemoteState) Empty() bool {
873 func (r *RemoteState) Equals(other *RemoteState) bool {
877 if r.Type != other.Type {
880 if len(r.Config) != len(other.Config) {
883 for k, v := range r.Config {
884 if other.Config[k] != v {
891 // OutputState is used to track the state relevant to a single output.
892 type OutputState struct {
893 // Sensitive describes whether the output is considered sensitive,
894 // which may lead to masking the value on screen in some cases.
895 Sensitive bool `json:"sensitive"`
896 // Type describes the structure of Value. Valid values are "string",
898 Type string `json:"type"`
899 // Value contains the value of the output, in the structure described
900 // by the Type field.
901 Value interface{} `json:"value"`
906 func (s *OutputState) Lock() { s.mu.Lock() }
907 func (s *OutputState) Unlock() { s.mu.Unlock() }
909 func (s *OutputState) String() string {
910 return fmt.Sprintf("%#v", s.Value)
913 // Equal compares two OutputState structures for equality. nil values are
915 func (s *OutputState) Equal(other *OutputState) bool {
916 if s == nil && other == nil {
920 if s == nil || other == nil {
926 if s.Type != other.Type {
930 if s.Sensitive != other.Sensitive {
934 if !reflect.DeepEqual(s.Value, other.Value) {
941 func (s *OutputState) deepcopy() *OutputState {
946 stateCopy, err := copystructure.Config{Lock: true}.Copy(s)
948 panic(fmt.Errorf("Error copying output value: %s", err))
951 return stateCopy.(*OutputState)
954 // ModuleState is used to track all the state relevant to a single
955 // module. Previous to Terraform 0.3, all state belonged to the "root"
957 type ModuleState struct {
958 // Path is the import path from the root module. Modules imports are
959 // always disjoint, so the path represents amodule tree
960 Path []string `json:"path"`
962 // Outputs declared by the module and maintained for each module
963 // even though only the root module technically needs to be kept.
964 // This allows operators to inspect values at the boundaries.
965 Outputs map[string]*OutputState `json:"outputs"`
967 // Resources is a mapping of the logically named resource to
968 // the state of the resource. Each resource may actually have
969 // N instances underneath, although a user only needs to think
970 // about the 1:1 case.
971 Resources map[string]*ResourceState `json:"resources"`
973 // Dependencies are a list of things that this module relies on
974 // existing to remain intact. For example: an module may depend
975 // on a VPC ID given by an aws_vpc resource.
977 // Terraform uses this information to build valid destruction
978 // orders and to warn the user if they're destroying a module that
979 // another resource depends on.
981 // Things can be put into this list that may not be managed by
982 // Terraform. If Terraform doesn't find a matching ID in the
983 // overall state, then it assumes it isn't managed and doesn't
985 Dependencies []string `json:"depends_on"`
990 func (s *ModuleState) Lock() { s.mu.Lock() }
991 func (s *ModuleState) Unlock() { s.mu.Unlock() }
993 // Equal tests whether one module state is equal to another.
994 func (m *ModuleState) Equal(other *ModuleState) bool {
998 // Paths must be equal
999 if !reflect.DeepEqual(m.Path, other.Path) {
1003 // Outputs must be equal
1004 if len(m.Outputs) != len(other.Outputs) {
1007 for k, v := range m.Outputs {
1008 if !other.Outputs[k].Equal(v) {
1013 // Dependencies must be equal. This sorts these in place but
1014 // this shouldn't cause any problems.
1015 sort.Strings(m.Dependencies)
1016 sort.Strings(other.Dependencies)
1017 if len(m.Dependencies) != len(other.Dependencies) {
1020 for i, d := range m.Dependencies {
1021 if other.Dependencies[i] != d {
1026 // Resources must be equal
1027 if len(m.Resources) != len(other.Resources) {
1030 for k, r := range m.Resources {
1031 otherR, ok := other.Resources[k]
1036 if !r.Equal(otherR) {
1044 // IsRoot says whether or not this module diff is for the root module.
1045 func (m *ModuleState) IsRoot() bool {
1048 return reflect.DeepEqual(m.Path, rootModulePath)
1051 // IsDescendent returns true if other is a descendent of this module.
1052 func (m *ModuleState) IsDescendent(other *ModuleState) bool {
1057 return len(other.Path) > i && reflect.DeepEqual(other.Path[:i], m.Path)
1060 // Orphans returns a list of keys of resources that are in the State
1061 // but aren't present in the configuration itself. Hence, these keys
1062 // represent the state of resources that are orphans.
1063 func (m *ModuleState) Orphans(c *config.Config) []string {
1067 keys := make(map[string]struct{})
1068 for k, _ := range m.Resources {
1069 keys[k] = struct{}{}
1073 for _, r := range c.Resources {
1074 delete(keys, r.Id())
1076 for k, _ := range keys {
1077 if strings.HasPrefix(k, r.Id()+".") {
1084 result := make([]string, 0, len(keys))
1085 for k, _ := range keys {
1086 result = append(result, k)
1092 // View returns a view with the given resource prefix.
1093 func (m *ModuleState) View(id string) *ModuleState {
1099 for k, _ := range r.Resources {
1100 if id == k || strings.HasPrefix(k, id+".") {
1104 delete(r.Resources, k)
1110 func (m *ModuleState) init() {
1117 if m.Outputs == nil {
1118 m.Outputs = make(map[string]*OutputState)
1120 if m.Resources == nil {
1121 m.Resources = make(map[string]*ResourceState)
1124 if m.Dependencies == nil {
1125 m.Dependencies = make([]string, 0)
1128 for _, rs := range m.Resources {
1133 func (m *ModuleState) deepcopy() *ModuleState {
1138 stateCopy, err := copystructure.Config{Lock: true}.Copy(m)
1143 return stateCopy.(*ModuleState)
1146 // prune is used to remove any resources that are no longer required
1147 func (m *ModuleState) prune() {
1151 for k, v := range m.Resources {
1152 if v == nil || (v.Primary == nil || v.Primary.ID == "") && len(v.Deposed) == 0 {
1153 delete(m.Resources, k)
1160 for k, v := range m.Outputs {
1161 if v.Value == config.UnknownVariableValue {
1162 delete(m.Outputs, k)
1166 m.Dependencies = uniqueStrings(m.Dependencies)
1169 func (m *ModuleState) sort() {
1170 for _, v := range m.Resources {
1175 func (m *ModuleState) String() string {
1179 var buf bytes.Buffer
1181 if len(m.Resources) == 0 {
1182 buf.WriteString("<no state>")
1185 names := make([]string, 0, len(m.Resources))
1186 for name, _ := range m.Resources {
1187 names = append(names, name)
1190 sort.Sort(resourceNameSort(names))
1192 for _, k := range names {
1193 rs := m.Resources[k]
1195 if rs.Primary != nil {
1199 id = "<not created>"
1203 if rs.Primary.Tainted {
1204 taintStr = " (tainted)"
1208 if len(rs.Deposed) > 0 {
1209 deposedStr = fmt.Sprintf(" (%d deposed)", len(rs.Deposed))
1212 buf.WriteString(fmt.Sprintf("%s:%s%s\n", k, taintStr, deposedStr))
1213 buf.WriteString(fmt.Sprintf(" ID = %s\n", id))
1214 if rs.Provider != "" {
1215 buf.WriteString(fmt.Sprintf(" provider = %s\n", rs.Provider))
1218 var attributes map[string]string
1219 if rs.Primary != nil {
1220 attributes = rs.Primary.Attributes
1222 attrKeys := make([]string, 0, len(attributes))
1223 for ak, _ := range attributes {
1228 attrKeys = append(attrKeys, ak)
1231 sort.Strings(attrKeys)
1233 for _, ak := range attrKeys {
1234 av := attributes[ak]
1235 buf.WriteString(fmt.Sprintf(" %s = %s\n", ak, av))
1238 for idx, t := range rs.Deposed {
1241 taintStr = " (tainted)"
1243 buf.WriteString(fmt.Sprintf(" Deposed ID %d = %s%s\n", idx+1, t.ID, taintStr))
1246 if len(rs.Dependencies) > 0 {
1247 buf.WriteString(fmt.Sprintf("\n Dependencies:\n"))
1248 for _, dep := range rs.Dependencies {
1249 buf.WriteString(fmt.Sprintf(" %s\n", dep))
1254 if len(m.Outputs) > 0 {
1255 buf.WriteString("\nOutputs:\n\n")
1257 ks := make([]string, 0, len(m.Outputs))
1258 for k, _ := range m.Outputs {
1264 for _, k := range ks {
1266 switch vTyped := v.Value.(type) {
1268 buf.WriteString(fmt.Sprintf("%s = %s\n", k, vTyped))
1270 buf.WriteString(fmt.Sprintf("%s = %s\n", k, vTyped))
1271 case map[string]interface{}:
1272 var mapKeys []string
1273 for key, _ := range vTyped {
1274 mapKeys = append(mapKeys, key)
1276 sort.Strings(mapKeys)
1278 var mapBuf bytes.Buffer
1279 mapBuf.WriteString("{")
1280 for _, key := range mapKeys {
1281 mapBuf.WriteString(fmt.Sprintf("%s:%s ", key, vTyped[key]))
1283 mapBuf.WriteString("}")
1285 buf.WriteString(fmt.Sprintf("%s = %s\n", k, mapBuf.String()))
1293 // ResourceStateKey is a structured representation of the key used for the
1294 // ModuleState.Resources mapping
1295 type ResourceStateKey struct {
1298 Mode config.ResourceMode
1302 // Equal determines whether two ResourceStateKeys are the same
1303 func (rsk *ResourceStateKey) Equal(other *ResourceStateKey) bool {
1304 if rsk == nil || other == nil {
1307 if rsk.Mode != other.Mode {
1310 if rsk.Type != other.Type {
1313 if rsk.Name != other.Name {
1316 if rsk.Index != other.Index {
1322 func (rsk *ResourceStateKey) String() string {
1328 case config.ManagedResourceMode:
1330 case config.DataResourceMode:
1333 panic(fmt.Errorf("unknown resource mode %s", rsk.Mode))
1335 if rsk.Index == -1 {
1336 return fmt.Sprintf("%s%s.%s", prefix, rsk.Type, rsk.Name)
1338 return fmt.Sprintf("%s%s.%s.%d", prefix, rsk.Type, rsk.Name, rsk.Index)
1341 // ParseResourceStateKey accepts a key in the format used by
1342 // ModuleState.Resources and returns a resource name and resource index. In the
1343 // state, a resource has the format "type.name.index" or "type.name". In the
1344 // latter case, the index is returned as -1.
1345 func ParseResourceStateKey(k string) (*ResourceStateKey, error) {
1346 parts := strings.Split(k, ".")
1347 mode := config.ManagedResourceMode
1348 if len(parts) > 0 && parts[0] == "data" {
1349 mode = config.DataResourceMode
1350 // Don't need the constant "data" prefix for parsing
1351 // now that we've figured out the mode.
1354 if len(parts) < 2 || len(parts) > 3 {
1355 return nil, fmt.Errorf("Malformed resource state key: %s", k)
1357 rsk := &ResourceStateKey{
1363 if len(parts) == 3 {
1364 index, err := strconv.Atoi(parts[2])
1366 return nil, fmt.Errorf("Malformed resource state key index: %s", k)
1373 // ResourceState holds the state of a resource that is used so that
1374 // a provider can find and manage an existing resource as well as for
1375 // storing attributes that are used to populate variables of child
1378 // Attributes has attributes about the created resource that are
1379 // queryable in interpolation: "${type.id.attr}"
1381 // Extra is just extra data that a provider can return that we store
1382 // for later, but is not exposed in any way to the user.
1384 type ResourceState struct {
1385 // This is filled in and managed by Terraform, and is the resource
1386 // type itself such as "mycloud_instance". If a resource provider sets
1387 // this value, it won't be persisted.
1388 Type string `json:"type"`
1390 // Dependencies are a list of things that this resource relies on
1391 // existing to remain intact. For example: an AWS instance might
1392 // depend on a subnet (which itself might depend on a VPC, and so
1395 // Terraform uses this information to build valid destruction
1396 // orders and to warn the user if they're destroying a resource that
1397 // another resource depends on.
1399 // Things can be put into this list that may not be managed by
1400 // Terraform. If Terraform doesn't find a matching ID in the
1401 // overall state, then it assumes it isn't managed and doesn't
1403 Dependencies []string `json:"depends_on"`
1405 // Primary is the current active instance for this resource.
1406 // It can be replaced but only after a successful creation.
1407 // This is the instances on which providers will act.
1408 Primary *InstanceState `json:"primary"`
1410 // Deposed is used in the mechanics of CreateBeforeDestroy: the existing
1411 // Primary is Deposed to get it out of the way for the replacement Primary to
1412 // be created by Apply. If the replacement Primary creates successfully, the
1413 // Deposed instance is cleaned up.
1415 // If there were problems creating the replacement Primary, the Deposed
1416 // instance and the (now tainted) replacement Primary will be swapped so the
1417 // tainted replacement will be cleaned up instead.
1419 // An instance will remain in the Deposed list until it is successfully
1420 // destroyed and purged.
1421 Deposed []*InstanceState `json:"deposed"`
1423 // Provider is used when a resource is connected to a provider with an alias.
1424 // If this string is empty, the resource is connected to the default provider,
1425 // e.g. "aws_instance" goes with the "aws" provider.
1426 // If the resource block contained a "provider" key, that value will be set here.
1427 Provider string `json:"provider"`
1432 func (s *ResourceState) Lock() { s.mu.Lock() }
1433 func (s *ResourceState) Unlock() { s.mu.Unlock() }
1435 // Equal tests whether two ResourceStates are equal.
1436 func (s *ResourceState) Equal(other *ResourceState) bool {
1440 if s.Type != other.Type {
1444 if s.Provider != other.Provider {
1448 // Dependencies must be equal
1449 sort.Strings(s.Dependencies)
1450 sort.Strings(other.Dependencies)
1451 if len(s.Dependencies) != len(other.Dependencies) {
1454 for i, d := range s.Dependencies {
1455 if other.Dependencies[i] != d {
1460 // States must be equal
1461 if !s.Primary.Equal(other.Primary) {
1468 // Taint marks a resource as tainted.
1469 func (s *ResourceState) Taint() {
1473 if s.Primary != nil {
1474 s.Primary.Tainted = true
1478 // Untaint unmarks a resource as tainted.
1479 func (s *ResourceState) Untaint() {
1483 if s.Primary != nil {
1484 s.Primary.Tainted = false
1488 func (s *ResourceState) init() {
1492 if s.Primary == nil {
1493 s.Primary = &InstanceState{}
1497 if s.Dependencies == nil {
1498 s.Dependencies = []string{}
1501 if s.Deposed == nil {
1502 s.Deposed = make([]*InstanceState, 0)
1506 func (s *ResourceState) deepcopy() *ResourceState {
1507 copy, err := copystructure.Config{Lock: true}.Copy(s)
1512 return copy.(*ResourceState)
1515 // prune is used to remove any instances that are no longer required
1516 func (s *ResourceState) prune() {
1521 for i := 0; i < n; i++ {
1522 inst := s.Deposed[i]
1523 if inst == nil || inst.ID == "" {
1524 copy(s.Deposed[i:], s.Deposed[i+1:])
1525 s.Deposed[n-1] = nil
1530 s.Deposed = s.Deposed[:n]
1532 s.Dependencies = uniqueStrings(s.Dependencies)
1535 func (s *ResourceState) sort() {
1539 sort.Strings(s.Dependencies)
1542 func (s *ResourceState) String() string {
1546 var buf bytes.Buffer
1547 buf.WriteString(fmt.Sprintf("Type = %s", s.Type))
1551 // InstanceState is used to track the unique state information belonging
1552 // to a given instance.
1553 type InstanceState struct {
1554 // A unique ID for this resource. This is opaque to Terraform
1555 // and is only meant as a lookup mechanism for the providers.
1556 ID string `json:"id"`
1558 // Attributes are basic information about the resource. Any keys here
1559 // are accessible in variable format within Terraform configurations:
1560 // ${resourcetype.name.attribute}.
1561 Attributes map[string]string `json:"attributes"`
1563 // Ephemeral is used to store any state associated with this instance
1564 // that is necessary for the Terraform run to complete, but is not
1565 // persisted to a state file.
1566 Ephemeral EphemeralState `json:"-"`
1568 // Meta is a simple K/V map that is persisted to the State but otherwise
1569 // ignored by Terraform core. It's meant to be used for accounting by
1570 // external client code. The value here must only contain Go primitives
1572 Meta map[string]interface{} `json:"meta"`
1574 // Tainted is used to mark a resource for recreation.
1575 Tainted bool `json:"tainted"`
1580 func (s *InstanceState) Lock() { s.mu.Lock() }
1581 func (s *InstanceState) Unlock() { s.mu.Unlock() }
1583 func (s *InstanceState) init() {
1587 if s.Attributes == nil {
1588 s.Attributes = make(map[string]string)
1591 s.Meta = make(map[string]interface{})
1596 // Copy all the Fields from another InstanceState
1597 func (s *InstanceState) Set(from *InstanceState) {
1605 s.Attributes = from.Attributes
1606 s.Ephemeral = from.Ephemeral
1608 s.Tainted = from.Tainted
1611 func (s *InstanceState) DeepCopy() *InstanceState {
1612 copy, err := copystructure.Config{Lock: true}.Copy(s)
1617 return copy.(*InstanceState)
1620 func (s *InstanceState) Empty() bool {
1630 func (s *InstanceState) Equal(other *InstanceState) bool {
1631 // Short circuit some nil checks
1632 if s == nil || other == nil {
1638 // IDs must be equal
1639 if s.ID != other.ID {
1643 // Attributes must be equal
1644 if len(s.Attributes) != len(other.Attributes) {
1647 for k, v := range s.Attributes {
1648 otherV, ok := other.Attributes[k]
1658 // Meta must be equal
1659 if len(s.Meta) != len(other.Meta) {
1662 if s.Meta != nil && other.Meta != nil {
1663 // We only do the deep check if both are non-nil. If one is nil
1664 // we treat it as equal since their lengths are both zero (check
1666 if !reflect.DeepEqual(s.Meta, other.Meta) {
1671 if s.Tainted != other.Tainted {
1678 // MergeDiff takes a ResourceDiff and merges the attributes into
1679 // this resource state in order to generate a new state. This new
1680 // state can be used to provide updated attribute lookups for
1681 // variable interpolation.
1683 // If the diff attribute requires computing the value, and hence
1684 // won't be available until apply, the value is replaced with the
1686 func (s *InstanceState) MergeDiff(d *InstanceDiff) *InstanceState {
1687 result := s.DeepCopy()
1689 result = new(InstanceState)
1696 for k, v := range s.Attributes {
1697 result.Attributes[k] = v
1701 for k, diff := range d.CopyAttributes() {
1702 if diff.NewRemoved {
1703 delete(result.Attributes, k)
1706 if diff.NewComputed {
1707 result.Attributes[k] = config.UnknownVariableValue
1711 result.Attributes[k] = diff.New
1718 func (s *InstanceState) String() string {
1722 var buf bytes.Buffer
1724 if s == nil || s.ID == "" {
1725 return "<not created>"
1728 buf.WriteString(fmt.Sprintf("ID = %s\n", s.ID))
1730 attributes := s.Attributes
1731 attrKeys := make([]string, 0, len(attributes))
1732 for ak, _ := range attributes {
1737 attrKeys = append(attrKeys, ak)
1739 sort.Strings(attrKeys)
1741 for _, ak := range attrKeys {
1742 av := attributes[ak]
1743 buf.WriteString(fmt.Sprintf("%s = %s\n", ak, av))
1746 buf.WriteString(fmt.Sprintf("Tainted = %t\n", s.Tainted))
1751 // EphemeralState is used for transient state that is only kept in-memory
1752 type EphemeralState struct {
1753 // ConnInfo is used for the providers to export information which is
1754 // used to connect to the resource for provisioning. For example,
1755 // this could contain SSH or WinRM credentials.
1756 ConnInfo map[string]string `json:"-"`
1758 // Type is used to specify the resource type for this instance. This is only
1759 // required for import operations (as documented). If the documentation
1760 // doesn't state that you need to set this, then don't worry about
1762 Type string `json:"-"`
1765 func (e *EphemeralState) init() {
1766 if e.ConnInfo == nil {
1767 e.ConnInfo = make(map[string]string)
1771 func (e *EphemeralState) DeepCopy() *EphemeralState {
1772 copy, err := copystructure.Config{Lock: true}.Copy(e)
1777 return copy.(*EphemeralState)
1780 type jsonStateVersionIdentifier struct {
1781 Version int `json:"version"`
1784 // Check if this is a V0 format - the magic bytes at the start of the file
1785 // should be "tfstate" if so. We no longer support upgrading this type of
1786 // state but return an error message explaining to a user how they can
1787 // upgrade via the 0.6.x series.
1788 func testForV0State(buf *bufio.Reader) error {
1789 start, err := buf.Peek(len("tfstate"))
1791 return fmt.Errorf("Failed to check for magic bytes: %v", err)
1793 if string(start) == "tfstate" {
1794 return fmt.Errorf("Terraform 0.7 no longer supports upgrading the binary state\n" +
1795 "format which was used prior to Terraform 0.3. Please upgrade\n" +
1796 "this state file using Terraform 0.6.16 prior to using it with\n" +
1803 // ErrNoState is returned by ReadState when the io.Reader contains no data
1804 var ErrNoState = errors.New("no state")
1806 // ReadState reads a state structure out of a reader in the format that
1807 // was written by WriteState.
1808 func ReadState(src io.Reader) (*State, error) {
1809 buf := bufio.NewReader(src)
1810 if _, err := buf.Peek(1); err != nil {
1811 // the error is either io.EOF or "invalid argument", and both are from
1813 return nil, ErrNoState
1816 if err := testForV0State(buf); err != nil {
1820 // If we are JSON we buffer the whole thing in memory so we can read it twice.
1821 // This is suboptimal, but will work for now.
1822 jsonBytes, err := ioutil.ReadAll(buf)
1824 return nil, fmt.Errorf("Reading state file failed: %v", err)
1827 versionIdentifier := &jsonStateVersionIdentifier{}
1828 if err := json.Unmarshal(jsonBytes, versionIdentifier); err != nil {
1829 return nil, fmt.Errorf("Decoding state file version failed: %v", err)
1833 switch versionIdentifier.Version {
1835 return nil, fmt.Errorf("State version 0 is not supported as JSON.")
1837 v1State, err := ReadStateV1(jsonBytes)
1842 v2State, err := upgradeStateV1ToV2(v1State)
1847 v3State, err := upgradeStateV2ToV3(v2State)
1852 // increment the Serial whenever we upgrade state
1856 v2State, err := ReadStateV2(jsonBytes)
1860 v3State, err := upgradeStateV2ToV3(v2State)
1868 v3State, err := ReadStateV3(jsonBytes)
1875 return nil, fmt.Errorf("Terraform %s does not support state version %d, please update.",
1876 SemVersion.String(), versionIdentifier.Version)
1879 // If we reached this place we must have a result set
1881 panic("resulting state in load not set, assertion failed")
1884 // Prune the state when read it. Its possible to write unpruned states or
1885 // for a user to make a state unpruned (nil-ing a module state for example).
1888 // Validate the state file is valid
1889 if err := result.Validate(); err != nil {
1896 func ReadStateV1(jsonBytes []byte) (*stateV1, error) {
1897 v1State := &stateV1{}
1898 if err := json.Unmarshal(jsonBytes, v1State); err != nil {
1899 return nil, fmt.Errorf("Decoding state file failed: %v", err)
1902 if v1State.Version != 1 {
1903 return nil, fmt.Errorf("Decoded state version did not match the decoder selection: "+
1904 "read %d, expected 1", v1State.Version)
1910 func ReadStateV2(jsonBytes []byte) (*State, error) {
1912 if err := json.Unmarshal(jsonBytes, state); err != nil {
1913 return nil, fmt.Errorf("Decoding state file failed: %v", err)
1916 // Check the version, this to ensure we don't read a future
1917 // version that we don't understand
1918 if state.Version > StateVersion {
1919 return nil, fmt.Errorf("Terraform %s does not support state version %d, please update.",
1920 SemVersion.String(), state.Version)
1923 // Make sure the version is semantic
1924 if state.TFVersion != "" {
1925 if _, err := version.NewVersion(state.TFVersion); err != nil {
1926 return nil, fmt.Errorf(
1927 "State contains invalid version: %s\n\n"+
1928 "Terraform validates the version format prior to writing it. This\n"+
1929 "means that this is invalid of the state becoming corrupted through\n"+
1930 "some external means. Please manually modify the Terraform version\n"+
1931 "field to be a proper semantic version.",
1936 // catch any unitialized fields in the state
1945 func ReadStateV3(jsonBytes []byte) (*State, error) {
1947 if err := json.Unmarshal(jsonBytes, state); err != nil {
1948 return nil, fmt.Errorf("Decoding state file failed: %v", err)
1951 // Check the version, this to ensure we don't read a future
1952 // version that we don't understand
1953 if state.Version > StateVersion {
1954 return nil, fmt.Errorf("Terraform %s does not support state version %d, please update.",
1955 SemVersion.String(), state.Version)
1958 // Make sure the version is semantic
1959 if state.TFVersion != "" {
1960 if _, err := version.NewVersion(state.TFVersion); err != nil {
1961 return nil, fmt.Errorf(
1962 "State contains invalid version: %s\n\n"+
1963 "Terraform validates the version format prior to writing it. This\n"+
1964 "means that this is invalid of the state becoming corrupted through\n"+
1965 "some external means. Please manually modify the Terraform version\n"+
1966 "field to be a proper semantic version.",
1971 // catch any unitialized fields in the state
1977 // Now we write the state back out to detect any changes in normaliztion.
1978 // If our state is now written out differently, bump the serial number to
1979 // prevent conflicts.
1980 var buf bytes.Buffer
1981 err := WriteState(state, &buf)
1986 if !bytes.Equal(jsonBytes, buf.Bytes()) {
1987 log.Println("[INFO] state modified during read or write. incrementing serial number")
1994 // WriteState writes a state somewhere in a binary format.
1995 func WriteState(d *State, dst io.Writer) error {
1996 // writing a nil state is a noop.
2001 // make sure we have no uninitialized fields
2004 // Make sure it is sorted
2007 // Ensure the version is set
2008 d.Version = StateVersion
2010 // If the TFVersion is set, verify it. We used to just set the version
2011 // here, but this isn't safe since it changes the MD5 sum on some remote
2012 // state storage backends such as Atlas. We now leave it be if needed.
2013 if d.TFVersion != "" {
2014 if _, err := version.NewVersion(d.TFVersion); err != nil {
2016 "Error writing state, invalid version: %s\n\n"+
2017 "The Terraform version when writing the state must be a semantic\n"+
2023 // Encode the data in a human-friendly way
2024 data, err := json.MarshalIndent(d, "", " ")
2026 return fmt.Errorf("Failed to encode state: %s", err)
2029 // We append a newline to the data because MarshalIndent doesn't
2030 data = append(data, '\n')
2032 // Write the data out to the dst
2033 if _, err := io.Copy(dst, bytes.NewReader(data)); err != nil {
2034 return fmt.Errorf("Failed to write state: %v", err)
2040 // resourceNameSort implements the sort.Interface to sort name parts lexically for
2041 // strings and numerically for integer indexes.
2042 type resourceNameSort []string
2044 func (r resourceNameSort) Len() int { return len(r) }
2045 func (r resourceNameSort) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
2047 func (r resourceNameSort) Less(i, j int) bool {
2048 iParts := strings.Split(r[i], ".")
2049 jParts := strings.Split(r[j], ".")
2052 if len(jParts) < end {
2056 for idx := 0; idx < end; idx++ {
2057 if iParts[idx] == jParts[idx] {
2061 // sort on the first non-matching part
2062 iInt, iIntErr := strconv.Atoi(iParts[idx])
2063 jInt, jIntErr := strconv.Atoi(jParts[idx])
2066 case iIntErr == nil && jIntErr == nil:
2067 // sort numerically if both parts are integers
2069 case iIntErr == nil:
2070 // numbers sort before strings
2072 case jIntErr == nil:
2075 return iParts[idx] < jParts[idx]
2082 // moduleStateSort implements sort.Interface to sort module states
2083 type moduleStateSort []*ModuleState
2085 func (s moduleStateSort) Len() int {
2089 func (s moduleStateSort) Less(i, j int) bool {
2093 // If either is nil, then the nil one is "less" than
2094 if a == nil || b == nil {
2098 // If the lengths are different, then the shorter one always wins
2099 if len(a.Path) != len(b.Path) {
2100 return len(a.Path) < len(b.Path)
2103 // Otherwise, compare lexically
2104 return strings.Join(a.Path, ".") < strings.Join(b.Path, ".")
2107 func (s moduleStateSort) Swap(i, j int) {
2108 s[i], s[j] = s[j], s[i]
2111 const stateValidateErrMultiModule = `
2112 Multiple modules with the same path: %s
2114 This means that there are multiple entries in the "modules" field
2115 in your state file that point to the same module. This will cause Terraform
2116 to behave in unexpected and error prone ways and is invalid. Please back up
2117 and modify your state file manually to resolve this.