19 "github.com/hashicorp/go-multierror"
20 "github.com/hashicorp/go-uuid"
21 "github.com/hashicorp/go-version"
22 "github.com/hashicorp/terraform/config"
23 "github.com/mitchellh/copystructure"
25 tfversion "github.com/hashicorp/terraform/version"
29 // StateVersion is the current version for our state file
33 // rootModulePath is the path of the root module
34 var rootModulePath = []string{"root"}
36 // normalizeModulePath takes a raw module path and returns a path that
37 // has the rootModulePath prepended to it. If I could go back in time I
38 // would've never had a rootModulePath (empty path would be root). We can
39 // still fix this but thats a big refactor that my branch doesn't make sense
40 // for. Instead, this function normalizes paths.
41 func normalizeModulePath(p []string) []string {
42 k := len(rootModulePath)
44 // If we already have a root module prefix, we're done
45 if len(p) >= len(rootModulePath) {
46 if reflect.DeepEqual(p[:k], rootModulePath) {
52 result := make([]string, len(rootModulePath)+len(p))
53 copy(result, rootModulePath)
58 // State keeps track of a snapshot state-of-the-world that Terraform
59 // can use to keep track of what real world resources it is actually
62 // Version is the state file protocol version.
63 Version int `json:"version"`
65 // TFVersion is the version of Terraform that wrote this state.
66 TFVersion string `json:"terraform_version,omitempty"`
68 // Serial is incremented on any operation that modifies
69 // the State file. It is used to detect potentially conflicting
71 Serial int64 `json:"serial"`
73 // Lineage is set when a new, blank state is created and then
74 // never updated. This allows us to determine whether the serials
75 // of two states can be meaningfully compared.
76 // Apart from the guarantee that collisions between two lineages
77 // are very unlikely, this value is opaque and external callers
78 // should only compare lineage strings byte-for-byte for equality.
79 Lineage string `json:"lineage"`
81 // Remote is used to track the metadata required to
82 // pull and push state files from a remote storage endpoint.
83 Remote *RemoteState `json:"remote,omitempty"`
85 // Backend tracks the configuration for the backend in use with
86 // this state. This is used to track any changes in the backend
88 Backend *BackendState `json:"backend,omitempty"`
90 // Modules contains all the modules in a breadth-first order
91 Modules []*ModuleState `json:"modules"`
96 func (s *State) Lock() { s.mu.Lock() }
97 func (s *State) Unlock() { s.mu.Unlock() }
99 // NewState is used to initialize a blank state
100 func NewState() *State {
106 // Children returns the ModuleStates that are direct children of
107 // the given path. If the path is "root", for example, then children
108 // returned might be "root.child", but not "root.child.grandchild".
109 func (s *State) Children(path []string) []*ModuleState {
114 return s.children(path)
117 func (s *State) children(path []string) []*ModuleState {
118 result := make([]*ModuleState, 0)
119 for _, m := range s.Modules {
124 if len(m.Path) != len(path)+1 {
127 if !reflect.DeepEqual(path, m.Path[:len(path)]) {
131 result = append(result, m)
137 // AddModule adds the module with the given path to the state.
139 // This should be the preferred method to add module states since it
140 // allows us to optimize lookups later as well as control sorting.
141 func (s *State) AddModule(path []string) *ModuleState {
145 return s.addModule(path)
148 func (s *State) addModule(path []string) *ModuleState {
149 // check if the module exists first
150 m := s.moduleByPath(path)
155 m = &ModuleState{Path: path}
157 s.Modules = append(s.Modules, m)
162 // ModuleByPath is used to lookup the module state for the given path.
163 // This should be the preferred lookup mechanism as it allows for future
164 // lookup optimizations.
165 func (s *State) ModuleByPath(path []string) *ModuleState {
172 return s.moduleByPath(path)
175 func (s *State) moduleByPath(path []string) *ModuleState {
176 for _, mod := range s.Modules {
181 panic("missing module path")
183 if reflect.DeepEqual(mod.Path, path) {
190 // ModuleOrphans returns all the module orphans in this state by
191 // returning their full paths. These paths can be used with ModuleByPath
192 // to return the actual state.
193 func (s *State) ModuleOrphans(path []string, c *config.Config) [][]string {
197 return s.moduleOrphans(path, c)
201 func (s *State) moduleOrphans(path []string, c *config.Config) [][]string {
202 // direct keeps track of what direct children we have both in our config
203 // and in our state. childrenKeys keeps track of what isn't an orphan.
204 direct := make(map[string]struct{})
205 childrenKeys := make(map[string]struct{})
207 for _, m := range c.Modules {
208 childrenKeys[m.Name] = struct{}{}
209 direct[m.Name] = struct{}{}
213 // Go over the direct children and find any that aren't in our keys.
214 var orphans [][]string
215 for _, m := range s.children(path) {
216 key := m.Path[len(m.Path)-1]
218 // Record that we found this key as a direct child. We use this
219 // later to find orphan nested modules.
220 direct[key] = struct{}{}
222 // If we have a direct child still in our config, it is not an orphan
223 if _, ok := childrenKeys[key]; ok {
227 orphans = append(orphans, m.Path)
230 // Find the orphans that are nested...
231 for _, m := range s.Modules {
236 // We only want modules that are at least grandchildren
237 if len(m.Path) < len(path)+2 {
241 // If it isn't part of our tree, continue
242 if !reflect.DeepEqual(path, m.Path[:len(path)]) {
246 // If we have the direct child, then just skip it.
247 key := m.Path[len(path)]
248 if _, ok := direct[key]; ok {
252 orphanPath := m.Path[:len(path)+1]
254 // Don't double-add if we've already added this orphan (which can happen if
255 // there are multiple nested sub-modules that get orphaned together).
256 alreadyAdded := false
257 for _, o := range orphans {
258 if reflect.DeepEqual(o, orphanPath) {
268 orphans = append(orphans, orphanPath)
274 // Empty returns true if the state is empty.
275 func (s *State) Empty() bool {
282 return len(s.Modules) == 0
285 // HasResources returns true if the state contains any resources.
287 // This is similar to !s.Empty, but returns true also in the case where the
288 // state has modules but all of them are devoid of resources.
289 func (s *State) HasResources() bool {
294 for _, mod := range s.Modules {
295 if len(mod.Resources) > 0 {
303 // IsRemote returns true if State represents a state that exists and is
305 func (s *State) IsRemote() bool {
315 if s.Remote.Type == "" {
322 // Validate validates the integrity of this state file.
324 // Certain properties of the statefile are expected by Terraform in order
325 // to behave properly. The core of Terraform will assume that once it
326 // receives a State structure that it has been validated. This validation
327 // check should be called to ensure that.
329 // If this returns an error, then the user should be notified. The error
330 // response will include detailed information on the nature of the error.
331 func (s *State) Validate() error {
337 // !!!! FOR DEVELOPERS !!!!
339 // Any errors returned from this Validate function will BLOCK TERRAFORM
340 // from loading a state file. Therefore, this should only contain checks
341 // that are only resolvable through manual intervention.
343 // !!!! FOR DEVELOPERS !!!!
345 // Make sure there are no duplicate module states. We open a new
346 // block here so we can use basic variable names and future validations
349 found := make(map[string]struct{})
350 for _, ms := range s.Modules {
355 key := strings.Join(ms.Path, ".")
356 if _, ok := found[key]; ok {
357 result = multierror.Append(result, fmt.Errorf(
358 strings.TrimSpace(stateValidateErrMultiModule), key))
362 found[key] = struct{}{}
369 // Remove removes the item in the state at the given address, returning
370 // any errors that may have occurred.
372 // If the address references a module state or resource, it will delete
373 // all children as well. To check what will be deleted, use a StateFilter
375 func (s *State) Remove(addr ...string) error {
379 // Filter out what we need to delete
380 filter := &StateFilter{State: s}
381 results, err := filter.Filter(addr...)
386 // If we have no results, just exit early, we're not going to do anything.
387 // While what happens below is fairly fast, this is an important early
388 // exit since the prune below might modify the state more and we don't
389 // want to modify the state if we don't have to.
390 if len(results) == 0 {
394 // Go through each result and grab what we need
395 removed := make(map[interface{}]struct{})
396 for _, r := range results {
397 // Convert the path to our own type
398 path := append([]string{"root"}, r.Path...)
400 // If we removed this already, then ignore
401 if _, ok := removed[r.Value]; ok {
405 // If we removed the parent already, then ignore
407 if _, ok := removed[r.Parent.Value]; ok {
412 // Add this to the removed list
413 removed[r.Value] = struct{}{}
415 switch v := r.Value.(type) {
417 s.removeModule(path, v)
419 s.removeResource(path, v)
421 s.removeInstance(path, r.Parent.Value.(*ResourceState), v)
423 return fmt.Errorf("unknown type to delete: %T", r.Value)
427 // Prune since the removal functions often do the bare minimum to
428 // remove a thing and may leave around dangling empty modules, resources,
429 // etc. Prune will clean that all up.
435 func (s *State) removeModule(path []string, v *ModuleState) {
436 for i, m := range s.Modules {
438 s.Modules, s.Modules[len(s.Modules)-1] = append(s.Modules[:i], s.Modules[i+1:]...), nil
444 func (s *State) removeResource(path []string, v *ResourceState) {
445 // Get the module this resource lives in. If it doesn't exist, we're done.
446 mod := s.moduleByPath(path)
451 // Find this resource. This is a O(N) lookup when if we had the key
452 // it could be O(1) but even with thousands of resources this shouldn't
453 // matter right now. We can easily up performance here when the time comes.
454 for k, r := range mod.Resources {
457 delete(mod.Resources, k)
463 func (s *State) removeInstance(path []string, r *ResourceState, v *InstanceState) {
464 // Go through the resource and find the instance that matches this
465 // (if any) and remove it.
474 lists := [][]*InstanceState{r.Deposed}
475 for _, is := range lists {
476 for i, instance := range is {
478 // Found it, remove it
479 is, is[len(is)-1] = append(is[:i], is[i+1:]...), nil
488 // RootModule returns the ModuleState for the root module
489 func (s *State) RootModule() *ModuleState {
490 root := s.ModuleByPath(rootModulePath)
492 panic("missing root module")
497 // Equal tests if one state is equal to another.
498 func (s *State) Equal(other *State) bool {
499 // If one is nil, we do a direct check
500 if s == nil || other == nil {
506 return s.equal(other)
509 func (s *State) equal(other *State) bool {
510 if s == nil || other == nil {
514 // If the versions are different, they're certainly not equal
515 if s.Version != other.Version {
519 // If any of the modules are not equal, then this state isn't equal
520 if len(s.Modules) != len(other.Modules) {
523 for _, m := range s.Modules {
524 // This isn't very optimal currently but works.
525 otherM := other.moduleByPath(m.Path)
530 // If they're not equal, then we're not equal!
531 if !m.Equal(otherM) {
539 // MarshalEqual is similar to Equal but provides a stronger definition of
540 // "equal", where two states are equal if and only if their serialized form
541 // is byte-for-byte identical.
543 // This is primarily useful for callers that are trying to save snapshots
544 // of state to persistent storage, allowing them to detect when a new
545 // snapshot must be taken.
547 // Note that the serial number and lineage are included in the serialized form,
548 // so it's the caller's responsibility to properly manage these attributes
549 // so that this method is only called on two states that have the same
550 // serial and lineage, unless detecting such differences is desired.
551 func (s *State) MarshalEqual(other *State) bool {
552 if s == nil && other == nil {
554 } else if s == nil || other == nil {
558 recvBuf := &bytes.Buffer{}
559 otherBuf := &bytes.Buffer{}
561 err := WriteState(s, recvBuf)
563 // should never happen, since we're writing to a buffer
567 err = WriteState(other, otherBuf)
569 // should never happen, since we're writing to a buffer
573 return bytes.Equal(recvBuf.Bytes(), otherBuf.Bytes())
576 type StateAgeComparison int
579 StateAgeEqual StateAgeComparison = 0
580 StateAgeReceiverNewer StateAgeComparison = 1
581 StateAgeReceiverOlder StateAgeComparison = -1
584 // CompareAges compares one state with another for which is "older".
586 // This is a simple check using the state's serial, and is thus only as
587 // reliable as the serial itself. In the normal case, only one state
588 // exists for a given combination of lineage/serial, but Terraform
589 // does not guarantee this and so the result of this method should be
592 // Returns an integer that is negative if the receiver is older than
593 // the argument, positive if the converse, and zero if they are equal.
594 // An error is returned if the two states are not of the same lineage,
595 // in which case the integer returned has no meaning.
596 func (s *State) CompareAges(other *State) (StateAgeComparison, error) {
597 // nil states are "older" than actual states
599 case s != nil && other == nil:
600 return StateAgeReceiverNewer, nil
601 case s == nil && other != nil:
602 return StateAgeReceiverOlder, nil
603 case s == nil && other == nil:
604 return StateAgeEqual, nil
607 if !s.SameLineage(other) {
608 return StateAgeEqual, fmt.Errorf(
609 "can't compare two states of differing lineage",
617 case s.Serial < other.Serial:
618 return StateAgeReceiverOlder, nil
619 case s.Serial > other.Serial:
620 return StateAgeReceiverNewer, nil
622 return StateAgeEqual, nil
626 // SameLineage returns true only if the state given in argument belongs
627 // to the same "lineage" of states as the receiver.
628 func (s *State) SameLineage(other *State) bool {
632 // If one of the states has no lineage then it is assumed to predate
633 // this concept, and so we'll accept it as belonging to any lineage
634 // so that a lineage string can be assigned to newer versions
635 // without breaking compatibility with older versions.
636 if s.Lineage == "" || other.Lineage == "" {
640 return s.Lineage == other.Lineage
643 // DeepCopy performs a deep copy of the state structure and returns
645 func (s *State) DeepCopy() *State {
650 copy, err := copystructure.Config{Lock: true}.Copy(s)
658 // FromFutureTerraform checks if this state was written by a Terraform
659 // version from the future.
660 func (s *State) FromFutureTerraform() bool {
664 // No TF version means it is certainly from the past
665 if s.TFVersion == "" {
669 v := version.Must(version.NewVersion(s.TFVersion))
670 return tfversion.SemVer.LessThan(v)
673 func (s *State) Init() {
679 func (s *State) init() {
681 s.Version = StateVersion
684 if s.moduleByPath(rootModulePath) == nil {
685 s.addModule(rootModulePath)
689 for _, mod := range s.Modules {
701 func (s *State) EnsureHasLineage() {
708 func (s *State) ensureHasLineage() {
710 lineage, err := uuid.GenerateUUID()
712 panic(fmt.Errorf("Failed to generate lineage: %v", err))
715 log.Printf("[DEBUG] New state was assigned lineage %q\n", s.Lineage)
717 log.Printf("[TRACE] Preserving existing state lineage %q\n", s.Lineage)
721 // AddModuleState insert this module state and override any existing ModuleState
722 func (s *State) AddModuleState(mod *ModuleState) {
727 s.addModuleState(mod)
730 func (s *State) addModuleState(mod *ModuleState) {
731 for i, m := range s.Modules {
732 if reflect.DeepEqual(m.Path, mod.Path) {
738 s.Modules = append(s.Modules, mod)
742 // prune is used to remove any resources that are no longer required
743 func (s *State) prune() {
748 // Filter out empty modules.
749 // A module is always assumed to have a path, and it's length isn't always
750 // bounds checked later on. Modules may be "emptied" during destroy, but we
751 // never want to store those in the state.
752 for i := 0; i < len(s.Modules); i++ {
753 if s.Modules[i] == nil || len(s.Modules[i].Path) == 0 {
754 s.Modules = append(s.Modules[:i], s.Modules[i+1:]...)
759 for _, mod := range s.Modules {
762 if s.Remote != nil && s.Remote.Empty() {
767 // sort sorts the modules
768 func (s *State) sort() {
769 sort.Sort(moduleStateSort(s.Modules))
771 // Allow modules to be sorted
772 for _, m := range s.Modules {
779 func (s *State) String() string {
787 for _, m := range s.Modules {
790 // If we're the root module, we just write the output directly.
791 if reflect.DeepEqual(m.Path, rootModulePath) {
792 buf.WriteString(mStr + "\n")
796 buf.WriteString(fmt.Sprintf("module.%s:\n", strings.Join(m.Path[1:], ".")))
798 s := bufio.NewScanner(strings.NewReader(mStr))
805 buf.WriteString(fmt.Sprintf("%s\n", text))
809 return strings.TrimSpace(buf.String())
812 // BackendState stores the configuration to connect to a remote backend.
813 type BackendState struct {
814 Type string `json:"type"` // Backend type
815 Config map[string]interface{} `json:"config"` // Backend raw config
817 // Hash is the hash code to uniquely identify the original source
818 // configuration. We use this to detect when there is a change in
819 // configuration even when "type" isn't changed.
820 Hash uint64 `json:"hash"`
823 // Empty returns true if BackendState has no state.
824 func (s *BackendState) Empty() bool {
825 return s == nil || s.Type == ""
828 // Rehash returns a unique content hash for this backend's configuration
829 // as a uint64 value.
830 // The Hash stored in the backend state needs to match the config itself, but
831 // we need to compare the backend config after it has been combined with all
833 // This function must match the implementation used by config.Backend.
834 func (s *BackendState) Rehash() uint64 {
839 cfg := config.Backend{
841 RawConfig: &config.RawConfig{
849 // RemoteState is used to track the information about a remote
850 // state store that we push/pull state to.
851 type RemoteState struct {
852 // Type controls the client we use for the remote state
853 Type string `json:"type"`
855 // Config is used to store arbitrary configuration that
857 Config map[string]string `json:"config"`
862 func (s *RemoteState) Lock() { s.mu.Lock() }
863 func (s *RemoteState) Unlock() { s.mu.Unlock() }
865 func (r *RemoteState) init() {
870 r.Config = make(map[string]string)
874 func (r *RemoteState) deepcopy() *RemoteState {
878 confCopy := make(map[string]string, len(r.Config))
879 for k, v := range r.Config {
888 func (r *RemoteState) Empty() bool {
898 func (r *RemoteState) Equals(other *RemoteState) bool {
902 if r.Type != other.Type {
905 if len(r.Config) != len(other.Config) {
908 for k, v := range r.Config {
909 if other.Config[k] != v {
916 // OutputState is used to track the state relevant to a single output.
917 type OutputState struct {
918 // Sensitive describes whether the output is considered sensitive,
919 // which may lead to masking the value on screen in some cases.
920 Sensitive bool `json:"sensitive"`
921 // Type describes the structure of Value. Valid values are "string",
923 Type string `json:"type"`
924 // Value contains the value of the output, in the structure described
925 // by the Type field.
926 Value interface{} `json:"value"`
931 func (s *OutputState) Lock() { s.mu.Lock() }
932 func (s *OutputState) Unlock() { s.mu.Unlock() }
934 func (s *OutputState) String() string {
935 return fmt.Sprintf("%#v", s.Value)
938 // Equal compares two OutputState structures for equality. nil values are
940 func (s *OutputState) Equal(other *OutputState) bool {
941 if s == nil && other == nil {
945 if s == nil || other == nil {
951 if s.Type != other.Type {
955 if s.Sensitive != other.Sensitive {
959 if !reflect.DeepEqual(s.Value, other.Value) {
966 func (s *OutputState) deepcopy() *OutputState {
971 stateCopy, err := copystructure.Config{Lock: true}.Copy(s)
973 panic(fmt.Errorf("Error copying output value: %s", err))
976 return stateCopy.(*OutputState)
979 // ModuleState is used to track all the state relevant to a single
980 // module. Previous to Terraform 0.3, all state belonged to the "root"
982 type ModuleState struct {
983 // Path is the import path from the root module. Modules imports are
984 // always disjoint, so the path represents amodule tree
985 Path []string `json:"path"`
987 // Locals are kept only transiently in-memory, because we can always
989 Locals map[string]interface{} `json:"-"`
991 // Outputs declared by the module and maintained for each module
992 // even though only the root module technically needs to be kept.
993 // This allows operators to inspect values at the boundaries.
994 Outputs map[string]*OutputState `json:"outputs"`
996 // Resources is a mapping of the logically named resource to
997 // the state of the resource. Each resource may actually have
998 // N instances underneath, although a user only needs to think
999 // about the 1:1 case.
1000 Resources map[string]*ResourceState `json:"resources"`
1002 // Dependencies are a list of things that this module relies on
1003 // existing to remain intact. For example: an module may depend
1004 // on a VPC ID given by an aws_vpc resource.
1006 // Terraform uses this information to build valid destruction
1007 // orders and to warn the user if they're destroying a module that
1008 // another resource depends on.
1010 // Things can be put into this list that may not be managed by
1011 // Terraform. If Terraform doesn't find a matching ID in the
1012 // overall state, then it assumes it isn't managed and doesn't
1014 Dependencies []string `json:"depends_on"`
1019 func (s *ModuleState) Lock() { s.mu.Lock() }
1020 func (s *ModuleState) Unlock() { s.mu.Unlock() }
1022 // Equal tests whether one module state is equal to another.
1023 func (m *ModuleState) Equal(other *ModuleState) bool {
1027 // Paths must be equal
1028 if !reflect.DeepEqual(m.Path, other.Path) {
1032 // Outputs must be equal
1033 if len(m.Outputs) != len(other.Outputs) {
1036 for k, v := range m.Outputs {
1037 if !other.Outputs[k].Equal(v) {
1042 // Dependencies must be equal. This sorts these in place but
1043 // this shouldn't cause any problems.
1044 sort.Strings(m.Dependencies)
1045 sort.Strings(other.Dependencies)
1046 if len(m.Dependencies) != len(other.Dependencies) {
1049 for i, d := range m.Dependencies {
1050 if other.Dependencies[i] != d {
1055 // Resources must be equal
1056 if len(m.Resources) != len(other.Resources) {
1059 for k, r := range m.Resources {
1060 otherR, ok := other.Resources[k]
1065 if !r.Equal(otherR) {
1073 // IsRoot says whether or not this module diff is for the root module.
1074 func (m *ModuleState) IsRoot() bool {
1077 return reflect.DeepEqual(m.Path, rootModulePath)
1080 // IsDescendent returns true if other is a descendent of this module.
1081 func (m *ModuleState) IsDescendent(other *ModuleState) bool {
1086 return len(other.Path) > i && reflect.DeepEqual(other.Path[:i], m.Path)
1089 // Orphans returns a list of keys of resources that are in the State
1090 // but aren't present in the configuration itself. Hence, these keys
1091 // represent the state of resources that are orphans.
1092 func (m *ModuleState) Orphans(c *config.Config) []string {
1096 keys := make(map[string]struct{})
1097 for k := range m.Resources {
1098 keys[k] = struct{}{}
1102 for _, r := range c.Resources {
1103 delete(keys, r.Id())
1105 for k := range keys {
1106 if strings.HasPrefix(k, r.Id()+".") {
1113 result := make([]string, 0, len(keys))
1114 for k := range keys {
1115 result = append(result, k)
1121 // RemovedOutputs returns a list of outputs that are in the State but aren't
1122 // present in the configuration itself.
1123 func (m *ModuleState) RemovedOutputs(c *config.Config) []string {
1127 keys := make(map[string]struct{})
1128 for k := range m.Outputs {
1129 keys[k] = struct{}{}
1133 for _, o := range c.Outputs {
1134 delete(keys, o.Name)
1138 result := make([]string, 0, len(keys))
1139 for k := range keys {
1140 result = append(result, k)
1146 // View returns a view with the given resource prefix.
1147 func (m *ModuleState) View(id string) *ModuleState {
1153 for k, _ := range r.Resources {
1154 if id == k || strings.HasPrefix(k, id+".") {
1158 delete(r.Resources, k)
1164 func (m *ModuleState) init() {
1171 if m.Outputs == nil {
1172 m.Outputs = make(map[string]*OutputState)
1174 if m.Resources == nil {
1175 m.Resources = make(map[string]*ResourceState)
1178 if m.Dependencies == nil {
1179 m.Dependencies = make([]string, 0)
1182 for _, rs := range m.Resources {
1187 func (m *ModuleState) deepcopy() *ModuleState {
1192 stateCopy, err := copystructure.Config{Lock: true}.Copy(m)
1197 return stateCopy.(*ModuleState)
1200 // prune is used to remove any resources that are no longer required
1201 func (m *ModuleState) prune() {
1205 for k, v := range m.Resources {
1206 if v == nil || (v.Primary == nil || v.Primary.ID == "") && len(v.Deposed) == 0 {
1207 delete(m.Resources, k)
1214 for k, v := range m.Outputs {
1215 if v.Value == config.UnknownVariableValue {
1216 delete(m.Outputs, k)
1220 m.Dependencies = uniqueStrings(m.Dependencies)
1223 func (m *ModuleState) sort() {
1224 for _, v := range m.Resources {
1229 func (m *ModuleState) String() string {
1233 var buf bytes.Buffer
1235 if len(m.Resources) == 0 {
1236 buf.WriteString("<no state>")
1239 names := make([]string, 0, len(m.Resources))
1240 for name, _ := range m.Resources {
1241 names = append(names, name)
1244 sort.Sort(resourceNameSort(names))
1246 for _, k := range names {
1247 rs := m.Resources[k]
1249 if rs.Primary != nil {
1253 id = "<not created>"
1257 if rs.Primary.Tainted {
1258 taintStr = " (tainted)"
1262 if len(rs.Deposed) > 0 {
1263 deposedStr = fmt.Sprintf(" (%d deposed)", len(rs.Deposed))
1266 buf.WriteString(fmt.Sprintf("%s:%s%s\n", k, taintStr, deposedStr))
1267 buf.WriteString(fmt.Sprintf(" ID = %s\n", id))
1268 if rs.Provider != "" {
1269 buf.WriteString(fmt.Sprintf(" provider = %s\n", rs.Provider))
1272 var attributes map[string]string
1273 if rs.Primary != nil {
1274 attributes = rs.Primary.Attributes
1276 attrKeys := make([]string, 0, len(attributes))
1277 for ak, _ := range attributes {
1282 attrKeys = append(attrKeys, ak)
1285 sort.Strings(attrKeys)
1287 for _, ak := range attrKeys {
1288 av := attributes[ak]
1289 buf.WriteString(fmt.Sprintf(" %s = %s\n", ak, av))
1292 for idx, t := range rs.Deposed {
1295 taintStr = " (tainted)"
1297 buf.WriteString(fmt.Sprintf(" Deposed ID %d = %s%s\n", idx+1, t.ID, taintStr))
1300 if len(rs.Dependencies) > 0 {
1301 buf.WriteString(fmt.Sprintf("\n Dependencies:\n"))
1302 for _, dep := range rs.Dependencies {
1303 buf.WriteString(fmt.Sprintf(" %s\n", dep))
1308 if len(m.Outputs) > 0 {
1309 buf.WriteString("\nOutputs:\n\n")
1311 ks := make([]string, 0, len(m.Outputs))
1312 for k, _ := range m.Outputs {
1318 for _, k := range ks {
1320 switch vTyped := v.Value.(type) {
1322 buf.WriteString(fmt.Sprintf("%s = %s\n", k, vTyped))
1324 buf.WriteString(fmt.Sprintf("%s = %s\n", k, vTyped))
1325 case map[string]interface{}:
1326 var mapKeys []string
1327 for key, _ := range vTyped {
1328 mapKeys = append(mapKeys, key)
1330 sort.Strings(mapKeys)
1332 var mapBuf bytes.Buffer
1333 mapBuf.WriteString("{")
1334 for _, key := range mapKeys {
1335 mapBuf.WriteString(fmt.Sprintf("%s:%s ", key, vTyped[key]))
1337 mapBuf.WriteString("}")
1339 buf.WriteString(fmt.Sprintf("%s = %s\n", k, mapBuf.String()))
1347 func (m *ModuleState) Empty() bool {
1348 return len(m.Locals) == 0 && len(m.Outputs) == 0 && len(m.Resources) == 0
1351 // ResourceStateKey is a structured representation of the key used for the
1352 // ModuleState.Resources mapping
1353 type ResourceStateKey struct {
1356 Mode config.ResourceMode
1360 // Equal determines whether two ResourceStateKeys are the same
1361 func (rsk *ResourceStateKey) Equal(other *ResourceStateKey) bool {
1362 if rsk == nil || other == nil {
1365 if rsk.Mode != other.Mode {
1368 if rsk.Type != other.Type {
1371 if rsk.Name != other.Name {
1374 if rsk.Index != other.Index {
1380 func (rsk *ResourceStateKey) String() string {
1386 case config.ManagedResourceMode:
1388 case config.DataResourceMode:
1391 panic(fmt.Errorf("unknown resource mode %s", rsk.Mode))
1393 if rsk.Index == -1 {
1394 return fmt.Sprintf("%s%s.%s", prefix, rsk.Type, rsk.Name)
1396 return fmt.Sprintf("%s%s.%s.%d", prefix, rsk.Type, rsk.Name, rsk.Index)
1399 // ParseResourceStateKey accepts a key in the format used by
1400 // ModuleState.Resources and returns a resource name and resource index. In the
1401 // state, a resource has the format "type.name.index" or "type.name". In the
1402 // latter case, the index is returned as -1.
1403 func ParseResourceStateKey(k string) (*ResourceStateKey, error) {
1404 parts := strings.Split(k, ".")
1405 mode := config.ManagedResourceMode
1406 if len(parts) > 0 && parts[0] == "data" {
1407 mode = config.DataResourceMode
1408 // Don't need the constant "data" prefix for parsing
1409 // now that we've figured out the mode.
1412 if len(parts) < 2 || len(parts) > 3 {
1413 return nil, fmt.Errorf("Malformed resource state key: %s", k)
1415 rsk := &ResourceStateKey{
1421 if len(parts) == 3 {
1422 index, err := strconv.Atoi(parts[2])
1424 return nil, fmt.Errorf("Malformed resource state key index: %s", k)
1431 // ResourceState holds the state of a resource that is used so that
1432 // a provider can find and manage an existing resource as well as for
1433 // storing attributes that are used to populate variables of child
1436 // Attributes has attributes about the created resource that are
1437 // queryable in interpolation: "${type.id.attr}"
1439 // Extra is just extra data that a provider can return that we store
1440 // for later, but is not exposed in any way to the user.
1442 type ResourceState struct {
1443 // This is filled in and managed by Terraform, and is the resource
1444 // type itself such as "mycloud_instance". If a resource provider sets
1445 // this value, it won't be persisted.
1446 Type string `json:"type"`
1448 // Dependencies are a list of things that this resource relies on
1449 // existing to remain intact. For example: an AWS instance might
1450 // depend on a subnet (which itself might depend on a VPC, and so
1453 // Terraform uses this information to build valid destruction
1454 // orders and to warn the user if they're destroying a resource that
1455 // another resource depends on.
1457 // Things can be put into this list that may not be managed by
1458 // Terraform. If Terraform doesn't find a matching ID in the
1459 // overall state, then it assumes it isn't managed and doesn't
1461 Dependencies []string `json:"depends_on"`
1463 // Primary is the current active instance for this resource.
1464 // It can be replaced but only after a successful creation.
1465 // This is the instances on which providers will act.
1466 Primary *InstanceState `json:"primary"`
1468 // Deposed is used in the mechanics of CreateBeforeDestroy: the existing
1469 // Primary is Deposed to get it out of the way for the replacement Primary to
1470 // be created by Apply. If the replacement Primary creates successfully, the
1471 // Deposed instance is cleaned up.
1473 // If there were problems creating the replacement Primary, the Deposed
1474 // instance and the (now tainted) replacement Primary will be swapped so the
1475 // tainted replacement will be cleaned up instead.
1477 // An instance will remain in the Deposed list until it is successfully
1478 // destroyed and purged.
1479 Deposed []*InstanceState `json:"deposed"`
1481 // Provider is used when a resource is connected to a provider with an alias.
1482 // If this string is empty, the resource is connected to the default provider,
1483 // e.g. "aws_instance" goes with the "aws" provider.
1484 // If the resource block contained a "provider" key, that value will be set here.
1485 Provider string `json:"provider"`
1490 func (s *ResourceState) Lock() { s.mu.Lock() }
1491 func (s *ResourceState) Unlock() { s.mu.Unlock() }
1493 // Equal tests whether two ResourceStates are equal.
1494 func (s *ResourceState) Equal(other *ResourceState) bool {
1498 if s.Type != other.Type {
1502 if s.Provider != other.Provider {
1506 // Dependencies must be equal
1507 sort.Strings(s.Dependencies)
1508 sort.Strings(other.Dependencies)
1509 if len(s.Dependencies) != len(other.Dependencies) {
1512 for i, d := range s.Dependencies {
1513 if other.Dependencies[i] != d {
1518 // States must be equal
1519 if !s.Primary.Equal(other.Primary) {
1526 // Taint marks a resource as tainted.
1527 func (s *ResourceState) Taint() {
1531 if s.Primary != nil {
1532 s.Primary.Tainted = true
1536 // Untaint unmarks a resource as tainted.
1537 func (s *ResourceState) Untaint() {
1541 if s.Primary != nil {
1542 s.Primary.Tainted = false
1546 func (s *ResourceState) init() {
1550 if s.Primary == nil {
1551 s.Primary = &InstanceState{}
1555 if s.Dependencies == nil {
1556 s.Dependencies = []string{}
1559 if s.Deposed == nil {
1560 s.Deposed = make([]*InstanceState, 0)
1564 func (s *ResourceState) deepcopy() *ResourceState {
1565 copy, err := copystructure.Config{Lock: true}.Copy(s)
1570 return copy.(*ResourceState)
1573 // prune is used to remove any instances that are no longer required
1574 func (s *ResourceState) prune() {
1579 for i := 0; i < n; i++ {
1580 inst := s.Deposed[i]
1581 if inst == nil || inst.ID == "" {
1582 copy(s.Deposed[i:], s.Deposed[i+1:])
1583 s.Deposed[n-1] = nil
1588 s.Deposed = s.Deposed[:n]
1590 s.Dependencies = uniqueStrings(s.Dependencies)
1593 func (s *ResourceState) sort() {
1597 sort.Strings(s.Dependencies)
1600 func (s *ResourceState) String() string {
1604 var buf bytes.Buffer
1605 buf.WriteString(fmt.Sprintf("Type = %s", s.Type))
1609 // InstanceState is used to track the unique state information belonging
1610 // to a given instance.
1611 type InstanceState struct {
1612 // A unique ID for this resource. This is opaque to Terraform
1613 // and is only meant as a lookup mechanism for the providers.
1614 ID string `json:"id"`
1616 // Attributes are basic information about the resource. Any keys here
1617 // are accessible in variable format within Terraform configurations:
1618 // ${resourcetype.name.attribute}.
1619 Attributes map[string]string `json:"attributes"`
1621 // Ephemeral is used to store any state associated with this instance
1622 // that is necessary for the Terraform run to complete, but is not
1623 // persisted to a state file.
1624 Ephemeral EphemeralState `json:"-"`
1626 // Meta is a simple K/V map that is persisted to the State but otherwise
1627 // ignored by Terraform core. It's meant to be used for accounting by
1628 // external client code. The value here must only contain Go primitives
1630 Meta map[string]interface{} `json:"meta"`
1632 // Tainted is used to mark a resource for recreation.
1633 Tainted bool `json:"tainted"`
1638 func (s *InstanceState) Lock() { s.mu.Lock() }
1639 func (s *InstanceState) Unlock() { s.mu.Unlock() }
1641 func (s *InstanceState) init() {
1645 if s.Attributes == nil {
1646 s.Attributes = make(map[string]string)
1649 s.Meta = make(map[string]interface{})
1654 // Copy all the Fields from another InstanceState
1655 func (s *InstanceState) Set(from *InstanceState) {
1663 s.Attributes = from.Attributes
1664 s.Ephemeral = from.Ephemeral
1666 s.Tainted = from.Tainted
1669 func (s *InstanceState) DeepCopy() *InstanceState {
1670 copy, err := copystructure.Config{Lock: true}.Copy(s)
1675 return copy.(*InstanceState)
1678 func (s *InstanceState) Empty() bool {
1688 func (s *InstanceState) Equal(other *InstanceState) bool {
1689 // Short circuit some nil checks
1690 if s == nil || other == nil {
1696 // IDs must be equal
1697 if s.ID != other.ID {
1701 // Attributes must be equal
1702 if len(s.Attributes) != len(other.Attributes) {
1705 for k, v := range s.Attributes {
1706 otherV, ok := other.Attributes[k]
1716 // Meta must be equal
1717 if len(s.Meta) != len(other.Meta) {
1720 if s.Meta != nil && other.Meta != nil {
1721 // We only do the deep check if both are non-nil. If one is nil
1722 // we treat it as equal since their lengths are both zero (check
1725 // Since this can contain numeric values that may change types during
1726 // serialization, let's compare the serialized values.
1727 sMeta, err := json.Marshal(s.Meta)
1729 // marshaling primitives shouldn't ever error out
1732 otherMeta, err := json.Marshal(other.Meta)
1737 if !bytes.Equal(sMeta, otherMeta) {
1742 if s.Tainted != other.Tainted {
1749 // MergeDiff takes a ResourceDiff and merges the attributes into
1750 // this resource state in order to generate a new state. This new
1751 // state can be used to provide updated attribute lookups for
1752 // variable interpolation.
1754 // If the diff attribute requires computing the value, and hence
1755 // won't be available until apply, the value is replaced with the
1757 func (s *InstanceState) MergeDiff(d *InstanceDiff) *InstanceState {
1758 result := s.DeepCopy()
1760 result = new(InstanceState)
1767 for k, v := range s.Attributes {
1768 result.Attributes[k] = v
1772 for k, diff := range d.CopyAttributes() {
1773 if diff.NewRemoved {
1774 delete(result.Attributes, k)
1777 if diff.NewComputed {
1778 result.Attributes[k] = config.UnknownVariableValue
1782 result.Attributes[k] = diff.New
1789 func (s *InstanceState) String() string {
1793 var buf bytes.Buffer
1795 if s == nil || s.ID == "" {
1796 return "<not created>"
1799 buf.WriteString(fmt.Sprintf("ID = %s\n", s.ID))
1801 attributes := s.Attributes
1802 attrKeys := make([]string, 0, len(attributes))
1803 for ak, _ := range attributes {
1808 attrKeys = append(attrKeys, ak)
1810 sort.Strings(attrKeys)
1812 for _, ak := range attrKeys {
1813 av := attributes[ak]
1814 buf.WriteString(fmt.Sprintf("%s = %s\n", ak, av))
1817 buf.WriteString(fmt.Sprintf("Tainted = %t\n", s.Tainted))
1822 // EphemeralState is used for transient state that is only kept in-memory
1823 type EphemeralState struct {
1824 // ConnInfo is used for the providers to export information which is
1825 // used to connect to the resource for provisioning. For example,
1826 // this could contain SSH or WinRM credentials.
1827 ConnInfo map[string]string `json:"-"`
1829 // Type is used to specify the resource type for this instance. This is only
1830 // required for import operations (as documented). If the documentation
1831 // doesn't state that you need to set this, then don't worry about
1833 Type string `json:"-"`
1836 func (e *EphemeralState) init() {
1837 if e.ConnInfo == nil {
1838 e.ConnInfo = make(map[string]string)
1842 func (e *EphemeralState) DeepCopy() *EphemeralState {
1843 copy, err := copystructure.Config{Lock: true}.Copy(e)
1848 return copy.(*EphemeralState)
1851 type jsonStateVersionIdentifier struct {
1852 Version int `json:"version"`
1855 // Check if this is a V0 format - the magic bytes at the start of the file
1856 // should be "tfstate" if so. We no longer support upgrading this type of
1857 // state but return an error message explaining to a user how they can
1858 // upgrade via the 0.6.x series.
1859 func testForV0State(buf *bufio.Reader) error {
1860 start, err := buf.Peek(len("tfstate"))
1862 return fmt.Errorf("Failed to check for magic bytes: %v", err)
1864 if string(start) == "tfstate" {
1865 return fmt.Errorf("Terraform 0.7 no longer supports upgrading the binary state\n" +
1866 "format which was used prior to Terraform 0.3. Please upgrade\n" +
1867 "this state file using Terraform 0.6.16 prior to using it with\n" +
1874 // ErrNoState is returned by ReadState when the io.Reader contains no data
1875 var ErrNoState = errors.New("no state")
1877 // ReadState reads a state structure out of a reader in the format that
1878 // was written by WriteState.
1879 func ReadState(src io.Reader) (*State, error) {
1880 // check for a nil file specifically, since that produces a platform
1881 // specific error if we try to use it in a bufio.Reader.
1882 if f, ok := src.(*os.File); ok && f == nil {
1883 return nil, ErrNoState
1886 buf := bufio.NewReader(src)
1888 if _, err := buf.Peek(1); err != nil {
1890 return nil, ErrNoState
1895 if err := testForV0State(buf); err != nil {
1899 // If we are JSON we buffer the whole thing in memory so we can read it twice.
1900 // This is suboptimal, but will work for now.
1901 jsonBytes, err := ioutil.ReadAll(buf)
1903 return nil, fmt.Errorf("Reading state file failed: %v", err)
1906 versionIdentifier := &jsonStateVersionIdentifier{}
1907 if err := json.Unmarshal(jsonBytes, versionIdentifier); err != nil {
1908 return nil, fmt.Errorf("Decoding state file version failed: %v", err)
1912 switch versionIdentifier.Version {
1914 return nil, fmt.Errorf("State version 0 is not supported as JSON.")
1916 v1State, err := ReadStateV1(jsonBytes)
1921 v2State, err := upgradeStateV1ToV2(v1State)
1926 v3State, err := upgradeStateV2ToV3(v2State)
1931 // increment the Serial whenever we upgrade state
1935 v2State, err := ReadStateV2(jsonBytes)
1939 v3State, err := upgradeStateV2ToV3(v2State)
1947 v3State, err := ReadStateV3(jsonBytes)
1954 return nil, fmt.Errorf("Terraform %s does not support state version %d, please update.",
1955 tfversion.SemVer.String(), versionIdentifier.Version)
1958 // If we reached this place we must have a result set
1960 panic("resulting state in load not set, assertion failed")
1963 // Prune the state when read it. Its possible to write unpruned states or
1964 // for a user to make a state unpruned (nil-ing a module state for example).
1967 // Validate the state file is valid
1968 if err := result.Validate(); err != nil {
1975 func ReadStateV1(jsonBytes []byte) (*stateV1, error) {
1976 v1State := &stateV1{}
1977 if err := json.Unmarshal(jsonBytes, v1State); err != nil {
1978 return nil, fmt.Errorf("Decoding state file failed: %v", err)
1981 if v1State.Version != 1 {
1982 return nil, fmt.Errorf("Decoded state version did not match the decoder selection: "+
1983 "read %d, expected 1", v1State.Version)
1989 func ReadStateV2(jsonBytes []byte) (*State, error) {
1991 if err := json.Unmarshal(jsonBytes, state); err != nil {
1992 return nil, fmt.Errorf("Decoding state file failed: %v", err)
1995 // Check the version, this to ensure we don't read a future
1996 // version that we don't understand
1997 if state.Version > StateVersion {
1998 return nil, fmt.Errorf("Terraform %s does not support state version %d, please update.",
1999 tfversion.SemVer.String(), state.Version)
2002 // Make sure the version is semantic
2003 if state.TFVersion != "" {
2004 if _, err := version.NewVersion(state.TFVersion); err != nil {
2005 return nil, fmt.Errorf(
2006 "State contains invalid version: %s\n\n"+
2007 "Terraform validates the version format prior to writing it. This\n"+
2008 "means that this is invalid of the state becoming corrupted through\n"+
2009 "some external means. Please manually modify the Terraform version\n"+
2010 "field to be a proper semantic version.",
2015 // catch any unitialized fields in the state
2024 func ReadStateV3(jsonBytes []byte) (*State, error) {
2026 if err := json.Unmarshal(jsonBytes, state); err != nil {
2027 return nil, fmt.Errorf("Decoding state file failed: %v", err)
2030 // Check the version, this to ensure we don't read a future
2031 // version that we don't understand
2032 if state.Version > StateVersion {
2033 return nil, fmt.Errorf("Terraform %s does not support state version %d, please update.",
2034 tfversion.SemVer.String(), state.Version)
2037 // Make sure the version is semantic
2038 if state.TFVersion != "" {
2039 if _, err := version.NewVersion(state.TFVersion); err != nil {
2040 return nil, fmt.Errorf(
2041 "State contains invalid version: %s\n\n"+
2042 "Terraform validates the version format prior to writing it. This\n"+
2043 "means that this is invalid of the state becoming corrupted through\n"+
2044 "some external means. Please manually modify the Terraform version\n"+
2045 "field to be a proper semantic version.",
2050 // catch any unitialized fields in the state
2056 // Now we write the state back out to detect any changes in normaliztion.
2057 // If our state is now written out differently, bump the serial number to
2058 // prevent conflicts.
2059 var buf bytes.Buffer
2060 err := WriteState(state, &buf)
2065 if !bytes.Equal(jsonBytes, buf.Bytes()) {
2066 log.Println("[INFO] state modified during read or write. incrementing serial number")
2073 // WriteState writes a state somewhere in a binary format.
2074 func WriteState(d *State, dst io.Writer) error {
2075 // writing a nil state is a noop.
2080 // make sure we have no uninitialized fields
2083 // Make sure it is sorted
2086 // Ensure the version is set
2087 d.Version = StateVersion
2089 // If the TFVersion is set, verify it. We used to just set the version
2090 // here, but this isn't safe since it changes the MD5 sum on some remote
2091 // state storage backends such as Atlas. We now leave it be if needed.
2092 if d.TFVersion != "" {
2093 if _, err := version.NewVersion(d.TFVersion); err != nil {
2095 "Error writing state, invalid version: %s\n\n"+
2096 "The Terraform version when writing the state must be a semantic\n"+
2102 // Encode the data in a human-friendly way
2103 data, err := json.MarshalIndent(d, "", " ")
2105 return fmt.Errorf("Failed to encode state: %s", err)
2108 // We append a newline to the data because MarshalIndent doesn't
2109 data = append(data, '\n')
2111 // Write the data out to the dst
2112 if _, err := io.Copy(dst, bytes.NewReader(data)); err != nil {
2113 return fmt.Errorf("Failed to write state: %v", err)
2119 // resourceNameSort implements the sort.Interface to sort name parts lexically for
2120 // strings and numerically for integer indexes.
2121 type resourceNameSort []string
2123 func (r resourceNameSort) Len() int { return len(r) }
2124 func (r resourceNameSort) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
2126 func (r resourceNameSort) Less(i, j int) bool {
2127 iParts := strings.Split(r[i], ".")
2128 jParts := strings.Split(r[j], ".")
2131 if len(jParts) < end {
2135 for idx := 0; idx < end; idx++ {
2136 if iParts[idx] == jParts[idx] {
2140 // sort on the first non-matching part
2141 iInt, iIntErr := strconv.Atoi(iParts[idx])
2142 jInt, jIntErr := strconv.Atoi(jParts[idx])
2145 case iIntErr == nil && jIntErr == nil:
2146 // sort numerically if both parts are integers
2148 case iIntErr == nil:
2149 // numbers sort before strings
2151 case jIntErr == nil:
2154 return iParts[idx] < jParts[idx]
2161 // moduleStateSort implements sort.Interface to sort module states
2162 type moduleStateSort []*ModuleState
2164 func (s moduleStateSort) Len() int {
2168 func (s moduleStateSort) Less(i, j int) bool {
2172 // If either is nil, then the nil one is "less" than
2173 if a == nil || b == nil {
2177 // If the lengths are different, then the shorter one always wins
2178 if len(a.Path) != len(b.Path) {
2179 return len(a.Path) < len(b.Path)
2182 // Otherwise, compare lexically
2183 return strings.Join(a.Path, ".") < strings.Join(b.Path, ".")
2186 func (s moduleStateSort) Swap(i, j int) {
2187 s[i], s[j] = s[j], s[i]
2190 // StateCompatible returns an error if the state is not compatible with the
2191 // current version of terraform.
2192 func CheckStateVersion(state *State) error {
2197 if state.FromFutureTerraform() {
2198 return fmt.Errorf(stateInvalidTerraformVersionErr, state.TFVersion)
2203 const stateValidateErrMultiModule = `
2204 Multiple modules with the same path: %s
2206 This means that there are multiple entries in the "modules" field
2207 in your state file that point to the same module. This will cause Terraform
2208 to behave in unexpected and error prone ways and is invalid. Please back up
2209 and modify your state file manually to resolve this.
2212 const stateInvalidTerraformVersionErr = `
2213 Terraform doesn't allow running any operations against a state
2214 that was written by a future Terraform version. The state is
2215 reporting it is written by Terraform '%s'
2217 Please run at least that version of Terraform to continue.