github.com/rstandt/terraform@v0.12.32-0.20230710220336-b1063613405c/terraform/state.go (about)

     1  package terraform
     2  
     3  import (
     4  	"bufio"
     5  	"bytes"
     6  	"encoding/json"
     7  	"errors"
     8  	"fmt"
     9  	"io"
    10  	"io/ioutil"
    11  	"log"
    12  	"os"
    13  	"reflect"
    14  	"sort"
    15  	"strconv"
    16  	"strings"
    17  	"sync"
    18  
    19  	"github.com/hashicorp/errwrap"
    20  	multierror "github.com/hashicorp/go-multierror"
    21  	uuid "github.com/hashicorp/go-uuid"
    22  	version "github.com/hashicorp/go-version"
    23  	"github.com/hashicorp/hcl/v2"
    24  	"github.com/hashicorp/hcl/v2/hclsyntax"
    25  	"github.com/hashicorp/terraform/addrs"
    26  	"github.com/hashicorp/terraform/configs"
    27  	"github.com/hashicorp/terraform/configs/configschema"
    28  	"github.com/hashicorp/terraform/configs/hcl2shim"
    29  	"github.com/hashicorp/terraform/plans"
    30  	"github.com/hashicorp/terraform/tfdiags"
    31  	tfversion "github.com/hashicorp/terraform/version"
    32  	"github.com/mitchellh/copystructure"
    33  	"github.com/zclconf/go-cty/cty"
    34  	ctyjson "github.com/zclconf/go-cty/cty/json"
    35  )
    36  
    37  const (
    38  	// StateVersion is the current version for our state file
    39  	StateVersion = 4
    40  )
    41  
    42  // rootModulePath is the path of the root module
    43  var rootModulePath = []string{"root"}
    44  
    45  // normalizeModulePath transforms a legacy module path (which may or may not
    46  // have a redundant "root" label at the start of it) into an
    47  // addrs.ModuleInstance representing the same module.
    48  //
    49  // For legacy reasons, different parts of Terraform disagree about whether the
    50  // root module has the path []string{} or []string{"root"}, and so this
    51  // function accepts both and trims off the "root". An implication of this is
    52  // that it's not possible to actually have a module call in the root module
    53  // that is itself named "root", since that would be ambiguous.
    54  //
    55  // normalizeModulePath takes a raw module path and returns a path that
    56  // has the rootModulePath prepended to it. If I could go back in time I
    57  // would've never had a rootModulePath (empty path would be root). We can
    58  // still fix this but thats a big refactor that my branch doesn't make sense
    59  // for. Instead, this function normalizes paths.
    60  func normalizeModulePath(p []string) addrs.ModuleInstance {
    61  	// FIXME: Remove this once everyone is using addrs.ModuleInstance.
    62  
    63  	if len(p) > 0 && p[0] == "root" {
    64  		p = p[1:]
    65  	}
    66  
    67  	ret := make(addrs.ModuleInstance, len(p))
    68  	for i, name := range p {
    69  		// For now we don't actually support modules with multiple instances
    70  		// identified by keys, so we just treat every path element as a
    71  		// step with no key.
    72  		ret[i] = addrs.ModuleInstanceStep{
    73  			Name: name,
    74  		}
    75  	}
    76  	return ret
    77  }
    78  
    79  // State keeps track of a snapshot state-of-the-world that Terraform
    80  // can use to keep track of what real world resources it is actually
    81  // managing.
    82  type State struct {
    83  	// Version is the state file protocol version.
    84  	Version int `json:"version"`
    85  
    86  	// TFVersion is the version of Terraform that wrote this state.
    87  	TFVersion string `json:"terraform_version,omitempty"`
    88  
    89  	// Serial is incremented on any operation that modifies
    90  	// the State file. It is used to detect potentially conflicting
    91  	// updates.
    92  	Serial int64 `json:"serial"`
    93  
    94  	// Lineage is set when a new, blank state is created and then
    95  	// never updated. This allows us to determine whether the serials
    96  	// of two states can be meaningfully compared.
    97  	// Apart from the guarantee that collisions between two lineages
    98  	// are very unlikely, this value is opaque and external callers
    99  	// should only compare lineage strings byte-for-byte for equality.
   100  	Lineage string `json:"lineage"`
   101  
   102  	// Remote is used to track the metadata required to
   103  	// pull and push state files from a remote storage endpoint.
   104  	Remote *RemoteState `json:"remote,omitempty"`
   105  
   106  	// Backend tracks the configuration for the backend in use with
   107  	// this state. This is used to track any changes in the backend
   108  	// configuration.
   109  	Backend *BackendState `json:"backend,omitempty"`
   110  
   111  	// Modules contains all the modules in a breadth-first order
   112  	Modules []*ModuleState `json:"modules"`
   113  
   114  	mu sync.Mutex
   115  }
   116  
   117  func (s *State) Lock()   { s.mu.Lock() }
   118  func (s *State) Unlock() { s.mu.Unlock() }
   119  
   120  // NewState is used to initialize a blank state
   121  func NewState() *State {
   122  	s := &State{}
   123  	s.init()
   124  	return s
   125  }
   126  
   127  // Children returns the ModuleStates that are direct children of
   128  // the given path. If the path is "root", for example, then children
   129  // returned might be "root.child", but not "root.child.grandchild".
   130  func (s *State) Children(path []string) []*ModuleState {
   131  	s.Lock()
   132  	defer s.Unlock()
   133  	// TODO: test
   134  
   135  	return s.children(path)
   136  }
   137  
   138  func (s *State) children(path []string) []*ModuleState {
   139  	result := make([]*ModuleState, 0)
   140  	for _, m := range s.Modules {
   141  		if m == nil {
   142  			continue
   143  		}
   144  
   145  		if len(m.Path) != len(path)+1 {
   146  			continue
   147  		}
   148  		if !reflect.DeepEqual(path, m.Path[:len(path)]) {
   149  			continue
   150  		}
   151  
   152  		result = append(result, m)
   153  	}
   154  
   155  	return result
   156  }
   157  
   158  // AddModule adds the module with the given path to the state.
   159  //
   160  // This should be the preferred method to add module states since it
   161  // allows us to optimize lookups later as well as control sorting.
   162  func (s *State) AddModule(path addrs.ModuleInstance) *ModuleState {
   163  	s.Lock()
   164  	defer s.Unlock()
   165  
   166  	return s.addModule(path)
   167  }
   168  
   169  func (s *State) addModule(path addrs.ModuleInstance) *ModuleState {
   170  	// check if the module exists first
   171  	m := s.moduleByPath(path)
   172  	if m != nil {
   173  		return m
   174  	}
   175  
   176  	// Lower the new-style address into a legacy-style address.
   177  	// This requires that none of the steps have instance keys, which is
   178  	// true for all addresses at the time of implementing this because
   179  	// "count" and "for_each" are not yet implemented for modules.
   180  	// For the purposes of state, the legacy address format also includes
   181  	// a redundant extra prefix element "root". It is important to include
   182  	// this because the "prune" method will remove any module that has a
   183  	// path length less than one, and other parts of the state code will
   184  	// trim off the first element indiscriminately.
   185  	legacyPath := make([]string, len(path)+1)
   186  	legacyPath[0] = "root"
   187  	for i, step := range path {
   188  		if step.InstanceKey != addrs.NoKey {
   189  			// FIXME: Once the rest of Terraform is ready to use count and
   190  			// for_each, remove all of this and just write the addrs.ModuleInstance
   191  			// value itself into the ModuleState.
   192  			panic("state cannot represent modules with count or for_each keys")
   193  		}
   194  
   195  		legacyPath[i+1] = step.Name
   196  	}
   197  
   198  	m = &ModuleState{Path: legacyPath}
   199  	m.init()
   200  	s.Modules = append(s.Modules, m)
   201  	s.sort()
   202  	return m
   203  }
   204  
   205  // ModuleByPath is used to lookup the module state for the given path.
   206  // This should be the preferred lookup mechanism as it allows for future
   207  // lookup optimizations.
   208  func (s *State) ModuleByPath(path addrs.ModuleInstance) *ModuleState {
   209  	if s == nil {
   210  		return nil
   211  	}
   212  	s.Lock()
   213  	defer s.Unlock()
   214  
   215  	return s.moduleByPath(path)
   216  }
   217  
   218  func (s *State) moduleByPath(path addrs.ModuleInstance) *ModuleState {
   219  	for _, mod := range s.Modules {
   220  		if mod == nil {
   221  			continue
   222  		}
   223  		if mod.Path == nil {
   224  			panic("missing module path")
   225  		}
   226  		modPath := normalizeModulePath(mod.Path)
   227  		if modPath.String() == path.String() {
   228  			return mod
   229  		}
   230  	}
   231  	return nil
   232  }
   233  
   234  // Empty returns true if the state is empty.
   235  func (s *State) Empty() bool {
   236  	if s == nil {
   237  		return true
   238  	}
   239  	s.Lock()
   240  	defer s.Unlock()
   241  
   242  	return len(s.Modules) == 0
   243  }
   244  
   245  // HasResources returns true if the state contains any resources.
   246  //
   247  // This is similar to !s.Empty, but returns true also in the case where the
   248  // state has modules but all of them are devoid of resources.
   249  func (s *State) HasResources() bool {
   250  	if s.Empty() {
   251  		return false
   252  	}
   253  
   254  	for _, mod := range s.Modules {
   255  		if len(mod.Resources) > 0 {
   256  			return true
   257  		}
   258  	}
   259  
   260  	return false
   261  }
   262  
   263  // IsRemote returns true if State represents a state that exists and is
   264  // remote.
   265  func (s *State) IsRemote() bool {
   266  	if s == nil {
   267  		return false
   268  	}
   269  	s.Lock()
   270  	defer s.Unlock()
   271  
   272  	if s.Remote == nil {
   273  		return false
   274  	}
   275  	if s.Remote.Type == "" {
   276  		return false
   277  	}
   278  
   279  	return true
   280  }
   281  
   282  // Validate validates the integrity of this state file.
   283  //
   284  // Certain properties of the statefile are expected by Terraform in order
   285  // to behave properly. The core of Terraform will assume that once it
   286  // receives a State structure that it has been validated. This validation
   287  // check should be called to ensure that.
   288  //
   289  // If this returns an error, then the user should be notified. The error
   290  // response will include detailed information on the nature of the error.
   291  func (s *State) Validate() error {
   292  	s.Lock()
   293  	defer s.Unlock()
   294  
   295  	var result error
   296  
   297  	// !!!! FOR DEVELOPERS !!!!
   298  	//
   299  	// Any errors returned from this Validate function will BLOCK TERRAFORM
   300  	// from loading a state file. Therefore, this should only contain checks
   301  	// that are only resolvable through manual intervention.
   302  	//
   303  	// !!!! FOR DEVELOPERS !!!!
   304  
   305  	// Make sure there are no duplicate module states. We open a new
   306  	// block here so we can use basic variable names and future validations
   307  	// can do the same.
   308  	{
   309  		found := make(map[string]struct{})
   310  		for _, ms := range s.Modules {
   311  			if ms == nil {
   312  				continue
   313  			}
   314  
   315  			key := strings.Join(ms.Path, ".")
   316  			if _, ok := found[key]; ok {
   317  				result = multierror.Append(result, fmt.Errorf(
   318  					strings.TrimSpace(stateValidateErrMultiModule), key))
   319  				continue
   320  			}
   321  
   322  			found[key] = struct{}{}
   323  		}
   324  	}
   325  
   326  	return result
   327  }
   328  
   329  // Remove removes the item in the state at the given address, returning
   330  // any errors that may have occurred.
   331  //
   332  // If the address references a module state or resource, it will delete
   333  // all children as well. To check what will be deleted, use a StateFilter
   334  // first.
   335  func (s *State) Remove(addr ...string) error {
   336  	s.Lock()
   337  	defer s.Unlock()
   338  
   339  	// Filter out what we need to delete
   340  	filter := &StateFilter{State: s}
   341  	results, err := filter.Filter(addr...)
   342  	if err != nil {
   343  		return err
   344  	}
   345  
   346  	// If we have no results, just exit early, we're not going to do anything.
   347  	// While what happens below is fairly fast, this is an important early
   348  	// exit since the prune below might modify the state more and we don't
   349  	// want to modify the state if we don't have to.
   350  	if len(results) == 0 {
   351  		return nil
   352  	}
   353  
   354  	// Go through each result and grab what we need
   355  	removed := make(map[interface{}]struct{})
   356  	for _, r := range results {
   357  		// Convert the path to our own type
   358  		path := append([]string{"root"}, r.Path...)
   359  
   360  		// If we removed this already, then ignore
   361  		if _, ok := removed[r.Value]; ok {
   362  			continue
   363  		}
   364  
   365  		// If we removed the parent already, then ignore
   366  		if r.Parent != nil {
   367  			if _, ok := removed[r.Parent.Value]; ok {
   368  				continue
   369  			}
   370  		}
   371  
   372  		// Add this to the removed list
   373  		removed[r.Value] = struct{}{}
   374  
   375  		switch v := r.Value.(type) {
   376  		case *ModuleState:
   377  			s.removeModule(path, v)
   378  		case *ResourceState:
   379  			s.removeResource(path, v)
   380  		case *InstanceState:
   381  			s.removeInstance(path, r.Parent.Value.(*ResourceState), v)
   382  		default:
   383  			return fmt.Errorf("unknown type to delete: %T", r.Value)
   384  		}
   385  	}
   386  
   387  	// Prune since the removal functions often do the bare minimum to
   388  	// remove a thing and may leave around dangling empty modules, resources,
   389  	// etc. Prune will clean that all up.
   390  	s.prune()
   391  
   392  	return nil
   393  }
   394  
   395  func (s *State) removeModule(path []string, v *ModuleState) {
   396  	for i, m := range s.Modules {
   397  		if m == v {
   398  			s.Modules, s.Modules[len(s.Modules)-1] = append(s.Modules[:i], s.Modules[i+1:]...), nil
   399  			return
   400  		}
   401  	}
   402  }
   403  
   404  func (s *State) removeResource(path []string, v *ResourceState) {
   405  	// Get the module this resource lives in. If it doesn't exist, we're done.
   406  	mod := s.moduleByPath(normalizeModulePath(path))
   407  	if mod == nil {
   408  		return
   409  	}
   410  
   411  	// Find this resource. This is a O(N) lookup when if we had the key
   412  	// it could be O(1) but even with thousands of resources this shouldn't
   413  	// matter right now. We can easily up performance here when the time comes.
   414  	for k, r := range mod.Resources {
   415  		if r == v {
   416  			// Found it
   417  			delete(mod.Resources, k)
   418  			return
   419  		}
   420  	}
   421  }
   422  
   423  func (s *State) removeInstance(path []string, r *ResourceState, v *InstanceState) {
   424  	// Go through the resource and find the instance that matches this
   425  	// (if any) and remove it.
   426  
   427  	// Check primary
   428  	if r.Primary == v {
   429  		r.Primary = nil
   430  		return
   431  	}
   432  
   433  	// Check lists
   434  	lists := [][]*InstanceState{r.Deposed}
   435  	for _, is := range lists {
   436  		for i, instance := range is {
   437  			if instance == v {
   438  				// Found it, remove it
   439  				is, is[len(is)-1] = append(is[:i], is[i+1:]...), nil
   440  
   441  				// Done
   442  				return
   443  			}
   444  		}
   445  	}
   446  }
   447  
   448  // RootModule returns the ModuleState for the root module
   449  func (s *State) RootModule() *ModuleState {
   450  	root := s.ModuleByPath(addrs.RootModuleInstance)
   451  	if root == nil {
   452  		panic("missing root module")
   453  	}
   454  	return root
   455  }
   456  
   457  // Equal tests if one state is equal to another.
   458  func (s *State) Equal(other *State) bool {
   459  	// If one is nil, we do a direct check
   460  	if s == nil || other == nil {
   461  		return s == other
   462  	}
   463  
   464  	s.Lock()
   465  	defer s.Unlock()
   466  	return s.equal(other)
   467  }
   468  
   469  func (s *State) equal(other *State) bool {
   470  	if s == nil || other == nil {
   471  		return s == other
   472  	}
   473  
   474  	// If the versions are different, they're certainly not equal
   475  	if s.Version != other.Version {
   476  		return false
   477  	}
   478  
   479  	// If any of the modules are not equal, then this state isn't equal
   480  	if len(s.Modules) != len(other.Modules) {
   481  		return false
   482  	}
   483  	for _, m := range s.Modules {
   484  		// This isn't very optimal currently but works.
   485  		otherM := other.moduleByPath(normalizeModulePath(m.Path))
   486  		if otherM == nil {
   487  			return false
   488  		}
   489  
   490  		// If they're not equal, then we're not equal!
   491  		if !m.Equal(otherM) {
   492  			return false
   493  		}
   494  	}
   495  
   496  	return true
   497  }
   498  
   499  // MarshalEqual is similar to Equal but provides a stronger definition of
   500  // "equal", where two states are equal if and only if their serialized form
   501  // is byte-for-byte identical.
   502  //
   503  // This is primarily useful for callers that are trying to save snapshots
   504  // of state to persistent storage, allowing them to detect when a new
   505  // snapshot must be taken.
   506  //
   507  // Note that the serial number and lineage are included in the serialized form,
   508  // so it's the caller's responsibility to properly manage these attributes
   509  // so that this method is only called on two states that have the same
   510  // serial and lineage, unless detecting such differences is desired.
   511  func (s *State) MarshalEqual(other *State) bool {
   512  	if s == nil && other == nil {
   513  		return true
   514  	} else if s == nil || other == nil {
   515  		return false
   516  	}
   517  
   518  	recvBuf := &bytes.Buffer{}
   519  	otherBuf := &bytes.Buffer{}
   520  
   521  	err := WriteState(s, recvBuf)
   522  	if err != nil {
   523  		// should never happen, since we're writing to a buffer
   524  		panic(err)
   525  	}
   526  
   527  	err = WriteState(other, otherBuf)
   528  	if err != nil {
   529  		// should never happen, since we're writing to a buffer
   530  		panic(err)
   531  	}
   532  
   533  	return bytes.Equal(recvBuf.Bytes(), otherBuf.Bytes())
   534  }
   535  
   536  type StateAgeComparison int
   537  
   538  const (
   539  	StateAgeEqual         StateAgeComparison = 0
   540  	StateAgeReceiverNewer StateAgeComparison = 1
   541  	StateAgeReceiverOlder StateAgeComparison = -1
   542  )
   543  
   544  // CompareAges compares one state with another for which is "older".
   545  //
   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
   550  // used with care.
   551  //
   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
   558  	switch {
   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
   565  	}
   566  
   567  	if !s.SameLineage(other) {
   568  		return StateAgeEqual, fmt.Errorf(
   569  			"can't compare two states of differing lineage",
   570  		)
   571  	}
   572  
   573  	s.Lock()
   574  	defer s.Unlock()
   575  
   576  	switch {
   577  	case s.Serial < other.Serial:
   578  		return StateAgeReceiverOlder, nil
   579  	case s.Serial > other.Serial:
   580  		return StateAgeReceiverNewer, nil
   581  	default:
   582  		return StateAgeEqual, nil
   583  	}
   584  }
   585  
   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 {
   589  	s.Lock()
   590  	defer s.Unlock()
   591  
   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 == "" {
   597  		return true
   598  	}
   599  
   600  	return s.Lineage == other.Lineage
   601  }
   602  
   603  // DeepCopy performs a deep copy of the state structure and returns
   604  // a new structure.
   605  func (s *State) DeepCopy() *State {
   606  	if s == nil {
   607  		return nil
   608  	}
   609  
   610  	copy, err := copystructure.Config{Lock: true}.Copy(s)
   611  	if err != nil {
   612  		panic(err)
   613  	}
   614  
   615  	return copy.(*State)
   616  }
   617  
   618  // FromFutureTerraform checks if this state was written by a Terraform
   619  // version from the future.
   620  func (s *State) FromFutureTerraform() bool {
   621  	s.Lock()
   622  	defer s.Unlock()
   623  
   624  	// No TF version means it is certainly from the past
   625  	if s.TFVersion == "" {
   626  		return false
   627  	}
   628  
   629  	v := version.Must(version.NewVersion(s.TFVersion))
   630  	return tfversion.SemVer.LessThan(v)
   631  }
   632  
   633  func (s *State) Init() {
   634  	s.Lock()
   635  	defer s.Unlock()
   636  	s.init()
   637  }
   638  
   639  func (s *State) init() {
   640  	if s.Version == 0 {
   641  		s.Version = StateVersion
   642  	}
   643  
   644  	if s.moduleByPath(addrs.RootModuleInstance) == nil {
   645  		s.addModule(addrs.RootModuleInstance)
   646  	}
   647  	s.ensureHasLineage()
   648  
   649  	for _, mod := range s.Modules {
   650  		if mod != nil {
   651  			mod.init()
   652  		}
   653  	}
   654  
   655  	if s.Remote != nil {
   656  		s.Remote.init()
   657  	}
   658  
   659  }
   660  
   661  func (s *State) EnsureHasLineage() {
   662  	s.Lock()
   663  	defer s.Unlock()
   664  
   665  	s.ensureHasLineage()
   666  }
   667  
   668  func (s *State) ensureHasLineage() {
   669  	if s.Lineage == "" {
   670  		lineage, err := uuid.GenerateUUID()
   671  		if err != nil {
   672  			panic(fmt.Errorf("Failed to generate lineage: %v", err))
   673  		}
   674  		s.Lineage = lineage
   675  		log.Printf("[DEBUG] New state was assigned lineage %q\n", s.Lineage)
   676  	} else {
   677  		log.Printf("[TRACE] Preserving existing state lineage %q\n", s.Lineage)
   678  	}
   679  }
   680  
   681  // AddModuleState insert this module state and override any existing ModuleState
   682  func (s *State) AddModuleState(mod *ModuleState) {
   683  	mod.init()
   684  	s.Lock()
   685  	defer s.Unlock()
   686  
   687  	s.addModuleState(mod)
   688  }
   689  
   690  func (s *State) addModuleState(mod *ModuleState) {
   691  	for i, m := range s.Modules {
   692  		if reflect.DeepEqual(m.Path, mod.Path) {
   693  			s.Modules[i] = mod
   694  			return
   695  		}
   696  	}
   697  
   698  	s.Modules = append(s.Modules, mod)
   699  	s.sort()
   700  }
   701  
   702  // prune is used to remove any resources that are no longer required
   703  func (s *State) prune() {
   704  	if s == nil {
   705  		return
   706  	}
   707  
   708  	// Filter out empty modules.
   709  	// A module is always assumed to have a path, and it's length isn't always
   710  	// bounds checked later on. Modules may be "emptied" during destroy, but we
   711  	// never want to store those in the state.
   712  	for i := 0; i < len(s.Modules); i++ {
   713  		if s.Modules[i] == nil || len(s.Modules[i].Path) == 0 {
   714  			s.Modules = append(s.Modules[:i], s.Modules[i+1:]...)
   715  			i--
   716  		}
   717  	}
   718  
   719  	for _, mod := range s.Modules {
   720  		mod.prune()
   721  	}
   722  	if s.Remote != nil && s.Remote.Empty() {
   723  		s.Remote = nil
   724  	}
   725  }
   726  
   727  // sort sorts the modules
   728  func (s *State) sort() {
   729  	sort.Sort(moduleStateSort(s.Modules))
   730  
   731  	// Allow modules to be sorted
   732  	for _, m := range s.Modules {
   733  		if m != nil {
   734  			m.sort()
   735  		}
   736  	}
   737  }
   738  
   739  func (s *State) String() string {
   740  	if s == nil {
   741  		return "<nil>"
   742  	}
   743  	s.Lock()
   744  	defer s.Unlock()
   745  
   746  	var buf bytes.Buffer
   747  	for _, m := range s.Modules {
   748  		mStr := m.String()
   749  
   750  		// If we're the root module, we just write the output directly.
   751  		if reflect.DeepEqual(m.Path, rootModulePath) {
   752  			buf.WriteString(mStr + "\n")
   753  			continue
   754  		}
   755  
   756  		buf.WriteString(fmt.Sprintf("module.%s:\n", strings.Join(m.Path[1:], ".")))
   757  
   758  		s := bufio.NewScanner(strings.NewReader(mStr))
   759  		for s.Scan() {
   760  			text := s.Text()
   761  			if text != "" {
   762  				text = "  " + text
   763  			}
   764  
   765  			buf.WriteString(fmt.Sprintf("%s\n", text))
   766  		}
   767  	}
   768  
   769  	return strings.TrimSpace(buf.String())
   770  }
   771  
   772  // BackendState stores the configuration to connect to a remote backend.
   773  type BackendState struct {
   774  	Type      string          `json:"type"`   // Backend type
   775  	ConfigRaw json.RawMessage `json:"config"` // Backend raw config
   776  	Hash      uint64          `json:"hash"`   // Hash of portion of configuration from config files
   777  }
   778  
   779  // Empty returns true if BackendState has no state.
   780  func (s *BackendState) Empty() bool {
   781  	return s == nil || s.Type == ""
   782  }
   783  
   784  // Config decodes the type-specific configuration object using the provided
   785  // schema and returns the result as a cty.Value.
   786  //
   787  // An error is returned if the stored configuration does not conform to the
   788  // given schema.
   789  func (s *BackendState) Config(schema *configschema.Block) (cty.Value, error) {
   790  	ty := schema.ImpliedType()
   791  	if s == nil {
   792  		return cty.NullVal(ty), nil
   793  	}
   794  	return ctyjson.Unmarshal(s.ConfigRaw, ty)
   795  }
   796  
   797  // SetConfig replaces (in-place) the type-specific configuration object using
   798  // the provided value and associated schema.
   799  //
   800  // An error is returned if the given value does not conform to the implied
   801  // type of the schema.
   802  func (s *BackendState) SetConfig(val cty.Value, schema *configschema.Block) error {
   803  	ty := schema.ImpliedType()
   804  	buf, err := ctyjson.Marshal(val, ty)
   805  	if err != nil {
   806  		return err
   807  	}
   808  	s.ConfigRaw = buf
   809  	return nil
   810  }
   811  
   812  // ForPlan produces an alternative representation of the reciever that is
   813  // suitable for storing in a plan. The current workspace must additionally
   814  // be provided, to be stored alongside the backend configuration.
   815  //
   816  // The backend configuration schema is required in order to properly
   817  // encode the backend-specific configuration settings.
   818  func (s *BackendState) ForPlan(schema *configschema.Block, workspaceName string) (*plans.Backend, error) {
   819  	if s == nil {
   820  		return nil, nil
   821  	}
   822  
   823  	configVal, err := s.Config(schema)
   824  	if err != nil {
   825  		return nil, errwrap.Wrapf("failed to decode backend config: {{err}}", err)
   826  	}
   827  	return plans.NewBackend(s.Type, configVal, schema, workspaceName)
   828  }
   829  
   830  // RemoteState is used to track the information about a remote
   831  // state store that we push/pull state to.
   832  type RemoteState struct {
   833  	// Type controls the client we use for the remote state
   834  	Type string `json:"type"`
   835  
   836  	// Config is used to store arbitrary configuration that
   837  	// is type specific
   838  	Config map[string]string `json:"config"`
   839  
   840  	mu sync.Mutex
   841  }
   842  
   843  func (s *RemoteState) Lock()   { s.mu.Lock() }
   844  func (s *RemoteState) Unlock() { s.mu.Unlock() }
   845  
   846  func (r *RemoteState) init() {
   847  	r.Lock()
   848  	defer r.Unlock()
   849  
   850  	if r.Config == nil {
   851  		r.Config = make(map[string]string)
   852  	}
   853  }
   854  
   855  func (r *RemoteState) deepcopy() *RemoteState {
   856  	r.Lock()
   857  	defer r.Unlock()
   858  
   859  	confCopy := make(map[string]string, len(r.Config))
   860  	for k, v := range r.Config {
   861  		confCopy[k] = v
   862  	}
   863  	return &RemoteState{
   864  		Type:   r.Type,
   865  		Config: confCopy,
   866  	}
   867  }
   868  
   869  func (r *RemoteState) Empty() bool {
   870  	if r == nil {
   871  		return true
   872  	}
   873  	r.Lock()
   874  	defer r.Unlock()
   875  
   876  	return r.Type == ""
   877  }
   878  
   879  func (r *RemoteState) Equals(other *RemoteState) bool {
   880  	r.Lock()
   881  	defer r.Unlock()
   882  
   883  	if r.Type != other.Type {
   884  		return false
   885  	}
   886  	if len(r.Config) != len(other.Config) {
   887  		return false
   888  	}
   889  	for k, v := range r.Config {
   890  		if other.Config[k] != v {
   891  			return false
   892  		}
   893  	}
   894  	return true
   895  }
   896  
   897  // OutputState is used to track the state relevant to a single output.
   898  type OutputState struct {
   899  	// Sensitive describes whether the output is considered sensitive,
   900  	// which may lead to masking the value on screen in some cases.
   901  	Sensitive bool `json:"sensitive"`
   902  	// Type describes the structure of Value. Valid values are "string",
   903  	// "map" and "list"
   904  	Type string `json:"type"`
   905  	// Value contains the value of the output, in the structure described
   906  	// by the Type field.
   907  	Value interface{} `json:"value"`
   908  
   909  	mu sync.Mutex
   910  }
   911  
   912  func (s *OutputState) Lock()   { s.mu.Lock() }
   913  func (s *OutputState) Unlock() { s.mu.Unlock() }
   914  
   915  func (s *OutputState) String() string {
   916  	return fmt.Sprintf("%#v", s.Value)
   917  }
   918  
   919  // Equal compares two OutputState structures for equality. nil values are
   920  // considered equal.
   921  func (s *OutputState) Equal(other *OutputState) bool {
   922  	if s == nil && other == nil {
   923  		return true
   924  	}
   925  
   926  	if s == nil || other == nil {
   927  		return false
   928  	}
   929  	s.Lock()
   930  	defer s.Unlock()
   931  
   932  	if s.Type != other.Type {
   933  		return false
   934  	}
   935  
   936  	if s.Sensitive != other.Sensitive {
   937  		return false
   938  	}
   939  
   940  	if !reflect.DeepEqual(s.Value, other.Value) {
   941  		return false
   942  	}
   943  
   944  	return true
   945  }
   946  
   947  func (s *OutputState) deepcopy() *OutputState {
   948  	if s == nil {
   949  		return nil
   950  	}
   951  
   952  	stateCopy, err := copystructure.Config{Lock: true}.Copy(s)
   953  	if err != nil {
   954  		panic(fmt.Errorf("Error copying output value: %s", err))
   955  	}
   956  
   957  	return stateCopy.(*OutputState)
   958  }
   959  
   960  // ModuleState is used to track all the state relevant to a single
   961  // module. Previous to Terraform 0.3, all state belonged to the "root"
   962  // module.
   963  type ModuleState struct {
   964  	// Path is the import path from the root module. Modules imports are
   965  	// always disjoint, so the path represents amodule tree
   966  	Path []string `json:"path"`
   967  
   968  	// Locals are kept only transiently in-memory, because we can always
   969  	// re-compute them.
   970  	Locals map[string]interface{} `json:"-"`
   971  
   972  	// Outputs declared by the module and maintained for each module
   973  	// even though only the root module technically needs to be kept.
   974  	// This allows operators to inspect values at the boundaries.
   975  	Outputs map[string]*OutputState `json:"outputs"`
   976  
   977  	// Resources is a mapping of the logically named resource to
   978  	// the state of the resource. Each resource may actually have
   979  	// N instances underneath, although a user only needs to think
   980  	// about the 1:1 case.
   981  	Resources map[string]*ResourceState `json:"resources"`
   982  
   983  	// Dependencies are a list of things that this module relies on
   984  	// existing to remain intact. For example: an module may depend
   985  	// on a VPC ID given by an aws_vpc resource.
   986  	//
   987  	// Terraform uses this information to build valid destruction
   988  	// orders and to warn the user if they're destroying a module that
   989  	// another resource depends on.
   990  	//
   991  	// Things can be put into this list that may not be managed by
   992  	// Terraform. If Terraform doesn't find a matching ID in the
   993  	// overall state, then it assumes it isn't managed and doesn't
   994  	// worry about it.
   995  	Dependencies []string `json:"depends_on"`
   996  
   997  	mu sync.Mutex
   998  }
   999  
  1000  func (s *ModuleState) Lock()   { s.mu.Lock() }
  1001  func (s *ModuleState) Unlock() { s.mu.Unlock() }
  1002  
  1003  // Equal tests whether one module state is equal to another.
  1004  func (m *ModuleState) Equal(other *ModuleState) bool {
  1005  	m.Lock()
  1006  	defer m.Unlock()
  1007  
  1008  	// Paths must be equal
  1009  	if !reflect.DeepEqual(m.Path, other.Path) {
  1010  		return false
  1011  	}
  1012  
  1013  	// Outputs must be equal
  1014  	if len(m.Outputs) != len(other.Outputs) {
  1015  		return false
  1016  	}
  1017  	for k, v := range m.Outputs {
  1018  		if !other.Outputs[k].Equal(v) {
  1019  			return false
  1020  		}
  1021  	}
  1022  
  1023  	// Dependencies must be equal. This sorts these in place but
  1024  	// this shouldn't cause any problems.
  1025  	sort.Strings(m.Dependencies)
  1026  	sort.Strings(other.Dependencies)
  1027  	if len(m.Dependencies) != len(other.Dependencies) {
  1028  		return false
  1029  	}
  1030  	for i, d := range m.Dependencies {
  1031  		if other.Dependencies[i] != d {
  1032  			return false
  1033  		}
  1034  	}
  1035  
  1036  	// Resources must be equal
  1037  	if len(m.Resources) != len(other.Resources) {
  1038  		return false
  1039  	}
  1040  	for k, r := range m.Resources {
  1041  		otherR, ok := other.Resources[k]
  1042  		if !ok {
  1043  			return false
  1044  		}
  1045  
  1046  		if !r.Equal(otherR) {
  1047  			return false
  1048  		}
  1049  	}
  1050  
  1051  	return true
  1052  }
  1053  
  1054  // IsRoot says whether or not this module diff is for the root module.
  1055  func (m *ModuleState) IsRoot() bool {
  1056  	m.Lock()
  1057  	defer m.Unlock()
  1058  	return reflect.DeepEqual(m.Path, rootModulePath)
  1059  }
  1060  
  1061  // IsDescendent returns true if other is a descendent of this module.
  1062  func (m *ModuleState) IsDescendent(other *ModuleState) bool {
  1063  	m.Lock()
  1064  	defer m.Unlock()
  1065  
  1066  	i := len(m.Path)
  1067  	return len(other.Path) > i && reflect.DeepEqual(other.Path[:i], m.Path)
  1068  }
  1069  
  1070  // Orphans returns a list of keys of resources that are in the State
  1071  // but aren't present in the configuration itself. Hence, these keys
  1072  // represent the state of resources that are orphans.
  1073  func (m *ModuleState) Orphans(c *configs.Module) []addrs.ResourceInstance {
  1074  	m.Lock()
  1075  	defer m.Unlock()
  1076  
  1077  	inConfig := make(map[string]struct{})
  1078  	if c != nil {
  1079  		for _, r := range c.ManagedResources {
  1080  			inConfig[r.Addr().String()] = struct{}{}
  1081  		}
  1082  		for _, r := range c.DataResources {
  1083  			inConfig[r.Addr().String()] = struct{}{}
  1084  		}
  1085  	}
  1086  
  1087  	var result []addrs.ResourceInstance
  1088  	for k := range m.Resources {
  1089  		// Since we've not yet updated state to use our new address format,
  1090  		// we need to do some shimming here.
  1091  		legacyAddr, err := parseResourceAddressInternal(k)
  1092  		if err != nil {
  1093  			// Suggests that the user tampered with the state, since we always
  1094  			// generate valid internal addresses.
  1095  			log.Printf("ModuleState has invalid resource key %q. Ignoring.", k)
  1096  			continue
  1097  		}
  1098  
  1099  		addr := legacyAddr.AbsResourceInstanceAddr().Resource
  1100  		compareKey := addr.Resource.String() // compare by resource address, ignoring instance key
  1101  		if _, exists := inConfig[compareKey]; !exists {
  1102  			result = append(result, addr)
  1103  		}
  1104  	}
  1105  	return result
  1106  }
  1107  
  1108  // RemovedOutputs returns a list of outputs that are in the State but aren't
  1109  // present in the configuration itself.
  1110  func (s *ModuleState) RemovedOutputs(outputs map[string]*configs.Output) []addrs.OutputValue {
  1111  	if outputs == nil {
  1112  		// If we got no output map at all then we'll just treat our set of
  1113  		// configured outputs as empty, since that suggests that they've all
  1114  		// been removed by removing their containing module.
  1115  		outputs = make(map[string]*configs.Output)
  1116  	}
  1117  
  1118  	s.Lock()
  1119  	defer s.Unlock()
  1120  
  1121  	var ret []addrs.OutputValue
  1122  	for n := range s.Outputs {
  1123  		if _, declared := outputs[n]; !declared {
  1124  			ret = append(ret, addrs.OutputValue{
  1125  				Name: n,
  1126  			})
  1127  		}
  1128  	}
  1129  
  1130  	return ret
  1131  }
  1132  
  1133  // View returns a view with the given resource prefix.
  1134  func (m *ModuleState) View(id string) *ModuleState {
  1135  	if m == nil {
  1136  		return m
  1137  	}
  1138  
  1139  	r := m.deepcopy()
  1140  	for k, _ := range r.Resources {
  1141  		if id == k || strings.HasPrefix(k, id+".") {
  1142  			continue
  1143  		}
  1144  
  1145  		delete(r.Resources, k)
  1146  	}
  1147  
  1148  	return r
  1149  }
  1150  
  1151  func (m *ModuleState) init() {
  1152  	m.Lock()
  1153  	defer m.Unlock()
  1154  
  1155  	if m.Path == nil {
  1156  		m.Path = []string{}
  1157  	}
  1158  	if m.Outputs == nil {
  1159  		m.Outputs = make(map[string]*OutputState)
  1160  	}
  1161  	if m.Resources == nil {
  1162  		m.Resources = make(map[string]*ResourceState)
  1163  	}
  1164  
  1165  	if m.Dependencies == nil {
  1166  		m.Dependencies = make([]string, 0)
  1167  	}
  1168  
  1169  	for _, rs := range m.Resources {
  1170  		rs.init()
  1171  	}
  1172  }
  1173  
  1174  func (m *ModuleState) deepcopy() *ModuleState {
  1175  	if m == nil {
  1176  		return nil
  1177  	}
  1178  
  1179  	stateCopy, err := copystructure.Config{Lock: true}.Copy(m)
  1180  	if err != nil {
  1181  		panic(err)
  1182  	}
  1183  
  1184  	return stateCopy.(*ModuleState)
  1185  }
  1186  
  1187  // prune is used to remove any resources that are no longer required
  1188  func (m *ModuleState) prune() {
  1189  	m.Lock()
  1190  	defer m.Unlock()
  1191  
  1192  	for k, v := range m.Resources {
  1193  		if v == nil || (v.Primary == nil || v.Primary.ID == "") && len(v.Deposed) == 0 {
  1194  			delete(m.Resources, k)
  1195  			continue
  1196  		}
  1197  
  1198  		v.prune()
  1199  	}
  1200  
  1201  	for k, v := range m.Outputs {
  1202  		if v.Value == hcl2shim.UnknownVariableValue {
  1203  			delete(m.Outputs, k)
  1204  		}
  1205  	}
  1206  
  1207  	m.Dependencies = uniqueStrings(m.Dependencies)
  1208  }
  1209  
  1210  func (m *ModuleState) sort() {
  1211  	for _, v := range m.Resources {
  1212  		v.sort()
  1213  	}
  1214  }
  1215  
  1216  func (m *ModuleState) String() string {
  1217  	m.Lock()
  1218  	defer m.Unlock()
  1219  
  1220  	var buf bytes.Buffer
  1221  
  1222  	if len(m.Resources) == 0 {
  1223  		buf.WriteString("<no state>")
  1224  	}
  1225  
  1226  	names := make([]string, 0, len(m.Resources))
  1227  	for name, _ := range m.Resources {
  1228  		names = append(names, name)
  1229  	}
  1230  
  1231  	sort.Sort(resourceNameSort(names))
  1232  
  1233  	for _, k := range names {
  1234  		rs := m.Resources[k]
  1235  		var id string
  1236  		if rs.Primary != nil {
  1237  			id = rs.Primary.ID
  1238  		}
  1239  		if id == "" {
  1240  			id = "<not created>"
  1241  		}
  1242  
  1243  		taintStr := ""
  1244  		if rs.Primary.Tainted {
  1245  			taintStr = " (tainted)"
  1246  		}
  1247  
  1248  		deposedStr := ""
  1249  		if len(rs.Deposed) > 0 {
  1250  			deposedStr = fmt.Sprintf(" (%d deposed)", len(rs.Deposed))
  1251  		}
  1252  
  1253  		buf.WriteString(fmt.Sprintf("%s:%s%s\n", k, taintStr, deposedStr))
  1254  		buf.WriteString(fmt.Sprintf("  ID = %s\n", id))
  1255  		if rs.Provider != "" {
  1256  			buf.WriteString(fmt.Sprintf("  provider = %s\n", rs.Provider))
  1257  		}
  1258  
  1259  		var attributes map[string]string
  1260  		if rs.Primary != nil {
  1261  			attributes = rs.Primary.Attributes
  1262  		}
  1263  		attrKeys := make([]string, 0, len(attributes))
  1264  		for ak, _ := range attributes {
  1265  			if ak == "id" {
  1266  				continue
  1267  			}
  1268  
  1269  			attrKeys = append(attrKeys, ak)
  1270  		}
  1271  
  1272  		sort.Strings(attrKeys)
  1273  
  1274  		for _, ak := range attrKeys {
  1275  			av := attributes[ak]
  1276  			buf.WriteString(fmt.Sprintf("  %s = %s\n", ak, av))
  1277  		}
  1278  
  1279  		for idx, t := range rs.Deposed {
  1280  			taintStr := ""
  1281  			if t.Tainted {
  1282  				taintStr = " (tainted)"
  1283  			}
  1284  			buf.WriteString(fmt.Sprintf("  Deposed ID %d = %s%s\n", idx+1, t.ID, taintStr))
  1285  		}
  1286  
  1287  		if len(rs.Dependencies) > 0 {
  1288  			buf.WriteString(fmt.Sprintf("\n  Dependencies:\n"))
  1289  			for _, dep := range rs.Dependencies {
  1290  				buf.WriteString(fmt.Sprintf("    %s\n", dep))
  1291  			}
  1292  		}
  1293  	}
  1294  
  1295  	if len(m.Outputs) > 0 {
  1296  		buf.WriteString("\nOutputs:\n\n")
  1297  
  1298  		ks := make([]string, 0, len(m.Outputs))
  1299  		for k, _ := range m.Outputs {
  1300  			ks = append(ks, k)
  1301  		}
  1302  
  1303  		sort.Strings(ks)
  1304  
  1305  		for _, k := range ks {
  1306  			v := m.Outputs[k]
  1307  			switch vTyped := v.Value.(type) {
  1308  			case string:
  1309  				buf.WriteString(fmt.Sprintf("%s = %s\n", k, vTyped))
  1310  			case []interface{}:
  1311  				buf.WriteString(fmt.Sprintf("%s = %s\n", k, vTyped))
  1312  			case map[string]interface{}:
  1313  				var mapKeys []string
  1314  				for key, _ := range vTyped {
  1315  					mapKeys = append(mapKeys, key)
  1316  				}
  1317  				sort.Strings(mapKeys)
  1318  
  1319  				var mapBuf bytes.Buffer
  1320  				mapBuf.WriteString("{")
  1321  				for _, key := range mapKeys {
  1322  					mapBuf.WriteString(fmt.Sprintf("%s:%s ", key, vTyped[key]))
  1323  				}
  1324  				mapBuf.WriteString("}")
  1325  
  1326  				buf.WriteString(fmt.Sprintf("%s = %s\n", k, mapBuf.String()))
  1327  			}
  1328  		}
  1329  	}
  1330  
  1331  	return buf.String()
  1332  }
  1333  
  1334  func (m *ModuleState) Empty() bool {
  1335  	return len(m.Locals) == 0 && len(m.Outputs) == 0 && len(m.Resources) == 0
  1336  }
  1337  
  1338  // ResourceStateKey is a structured representation of the key used for the
  1339  // ModuleState.Resources mapping
  1340  type ResourceStateKey struct {
  1341  	Name  string
  1342  	Type  string
  1343  	Mode  ResourceMode
  1344  	Index int
  1345  }
  1346  
  1347  // Equal determines whether two ResourceStateKeys are the same
  1348  func (rsk *ResourceStateKey) Equal(other *ResourceStateKey) bool {
  1349  	if rsk == nil || other == nil {
  1350  		return false
  1351  	}
  1352  	if rsk.Mode != other.Mode {
  1353  		return false
  1354  	}
  1355  	if rsk.Type != other.Type {
  1356  		return false
  1357  	}
  1358  	if rsk.Name != other.Name {
  1359  		return false
  1360  	}
  1361  	if rsk.Index != other.Index {
  1362  		return false
  1363  	}
  1364  	return true
  1365  }
  1366  
  1367  func (rsk *ResourceStateKey) String() string {
  1368  	if rsk == nil {
  1369  		return ""
  1370  	}
  1371  	var prefix string
  1372  	switch rsk.Mode {
  1373  	case ManagedResourceMode:
  1374  		prefix = ""
  1375  	case DataResourceMode:
  1376  		prefix = "data."
  1377  	default:
  1378  		panic(fmt.Errorf("unknown resource mode %s", rsk.Mode))
  1379  	}
  1380  	if rsk.Index == -1 {
  1381  		return fmt.Sprintf("%s%s.%s", prefix, rsk.Type, rsk.Name)
  1382  	}
  1383  	return fmt.Sprintf("%s%s.%s.%d", prefix, rsk.Type, rsk.Name, rsk.Index)
  1384  }
  1385  
  1386  // ParseResourceStateKey accepts a key in the format used by
  1387  // ModuleState.Resources and returns a resource name and resource index. In the
  1388  // state, a resource has the format "type.name.index" or "type.name". In the
  1389  // latter case, the index is returned as -1.
  1390  func ParseResourceStateKey(k string) (*ResourceStateKey, error) {
  1391  	parts := strings.Split(k, ".")
  1392  	mode := ManagedResourceMode
  1393  	if len(parts) > 0 && parts[0] == "data" {
  1394  		mode = DataResourceMode
  1395  		// Don't need the constant "data" prefix for parsing
  1396  		// now that we've figured out the mode.
  1397  		parts = parts[1:]
  1398  	}
  1399  	if len(parts) < 2 || len(parts) > 3 {
  1400  		return nil, fmt.Errorf("Malformed resource state key: %s", k)
  1401  	}
  1402  	rsk := &ResourceStateKey{
  1403  		Mode:  mode,
  1404  		Type:  parts[0],
  1405  		Name:  parts[1],
  1406  		Index: -1,
  1407  	}
  1408  	if len(parts) == 3 {
  1409  		index, err := strconv.Atoi(parts[2])
  1410  		if err != nil {
  1411  			return nil, fmt.Errorf("Malformed resource state key index: %s", k)
  1412  		}
  1413  		rsk.Index = index
  1414  	}
  1415  	return rsk, nil
  1416  }
  1417  
  1418  // ResourceState holds the state of a resource that is used so that
  1419  // a provider can find and manage an existing resource as well as for
  1420  // storing attributes that are used to populate variables of child
  1421  // resources.
  1422  //
  1423  // Attributes has attributes about the created resource that are
  1424  // queryable in interpolation: "${type.id.attr}"
  1425  //
  1426  // Extra is just extra data that a provider can return that we store
  1427  // for later, but is not exposed in any way to the user.
  1428  type ResourceState struct {
  1429  	// This is filled in and managed by Terraform, and is the resource
  1430  	// type itself such as "mycloud_instance". If a resource provider sets
  1431  	// this value, it won't be persisted.
  1432  	Type string `json:"type"`
  1433  
  1434  	// Dependencies are a list of things that this resource relies on
  1435  	// existing to remain intact. For example: an AWS instance might
  1436  	// depend on a subnet (which itself might depend on a VPC, and so
  1437  	// on).
  1438  	//
  1439  	// Terraform uses this information to build valid destruction
  1440  	// orders and to warn the user if they're destroying a resource that
  1441  	// another resource depends on.
  1442  	//
  1443  	// Things can be put into this list that may not be managed by
  1444  	// Terraform. If Terraform doesn't find a matching ID in the
  1445  	// overall state, then it assumes it isn't managed and doesn't
  1446  	// worry about it.
  1447  	Dependencies []string `json:"depends_on"`
  1448  
  1449  	// Primary is the current active instance for this resource.
  1450  	// It can be replaced but only after a successful creation.
  1451  	// This is the instances on which providers will act.
  1452  	Primary *InstanceState `json:"primary"`
  1453  
  1454  	// Deposed is used in the mechanics of CreateBeforeDestroy: the existing
  1455  	// Primary is Deposed to get it out of the way for the replacement Primary to
  1456  	// be created by Apply. If the replacement Primary creates successfully, the
  1457  	// Deposed instance is cleaned up.
  1458  	//
  1459  	// If there were problems creating the replacement Primary, the Deposed
  1460  	// instance and the (now tainted) replacement Primary will be swapped so the
  1461  	// tainted replacement will be cleaned up instead.
  1462  	//
  1463  	// An instance will remain in the Deposed list until it is successfully
  1464  	// destroyed and purged.
  1465  	Deposed []*InstanceState `json:"deposed"`
  1466  
  1467  	// Provider is used when a resource is connected to a provider with an alias.
  1468  	// If this string is empty, the resource is connected to the default provider,
  1469  	// e.g. "aws_instance" goes with the "aws" provider.
  1470  	// If the resource block contained a "provider" key, that value will be set here.
  1471  	Provider string `json:"provider"`
  1472  
  1473  	mu sync.Mutex
  1474  }
  1475  
  1476  func (s *ResourceState) Lock()   { s.mu.Lock() }
  1477  func (s *ResourceState) Unlock() { s.mu.Unlock() }
  1478  
  1479  // Equal tests whether two ResourceStates are equal.
  1480  func (s *ResourceState) Equal(other *ResourceState) bool {
  1481  	s.Lock()
  1482  	defer s.Unlock()
  1483  
  1484  	if s.Type != other.Type {
  1485  		return false
  1486  	}
  1487  
  1488  	if s.Provider != other.Provider {
  1489  		return false
  1490  	}
  1491  
  1492  	// Dependencies must be equal
  1493  	sort.Strings(s.Dependencies)
  1494  	sort.Strings(other.Dependencies)
  1495  	if len(s.Dependencies) != len(other.Dependencies) {
  1496  		return false
  1497  	}
  1498  	for i, d := range s.Dependencies {
  1499  		if other.Dependencies[i] != d {
  1500  			return false
  1501  		}
  1502  	}
  1503  
  1504  	// States must be equal
  1505  	if !s.Primary.Equal(other.Primary) {
  1506  		return false
  1507  	}
  1508  
  1509  	return true
  1510  }
  1511  
  1512  // Taint marks a resource as tainted.
  1513  func (s *ResourceState) Taint() {
  1514  	s.Lock()
  1515  	defer s.Unlock()
  1516  
  1517  	if s.Primary != nil {
  1518  		s.Primary.Tainted = true
  1519  	}
  1520  }
  1521  
  1522  // Untaint unmarks a resource as tainted.
  1523  func (s *ResourceState) Untaint() {
  1524  	s.Lock()
  1525  	defer s.Unlock()
  1526  
  1527  	if s.Primary != nil {
  1528  		s.Primary.Tainted = false
  1529  	}
  1530  }
  1531  
  1532  // ProviderAddr returns the provider address for the receiver, by parsing the
  1533  // string representation saved in state. An error can be returned if the
  1534  // value in state is corrupt.
  1535  func (s *ResourceState) ProviderAddr() (addrs.AbsProviderConfig, error) {
  1536  	var diags tfdiags.Diagnostics
  1537  
  1538  	str := s.Provider
  1539  	traversal, travDiags := hclsyntax.ParseTraversalAbs([]byte(str), "", hcl.Pos{Line: 1, Column: 1})
  1540  	diags = diags.Append(travDiags)
  1541  	if travDiags.HasErrors() {
  1542  		return addrs.AbsProviderConfig{}, diags.Err()
  1543  	}
  1544  
  1545  	addr, addrDiags := addrs.ParseAbsProviderConfig(traversal)
  1546  	diags = diags.Append(addrDiags)
  1547  	return addr, diags.Err()
  1548  }
  1549  
  1550  func (s *ResourceState) init() {
  1551  	s.Lock()
  1552  	defer s.Unlock()
  1553  
  1554  	if s.Primary == nil {
  1555  		s.Primary = &InstanceState{}
  1556  	}
  1557  	s.Primary.init()
  1558  
  1559  	if s.Dependencies == nil {
  1560  		s.Dependencies = []string{}
  1561  	}
  1562  
  1563  	if s.Deposed == nil {
  1564  		s.Deposed = make([]*InstanceState, 0)
  1565  	}
  1566  }
  1567  
  1568  func (s *ResourceState) deepcopy() *ResourceState {
  1569  	copy, err := copystructure.Config{Lock: true}.Copy(s)
  1570  	if err != nil {
  1571  		panic(err)
  1572  	}
  1573  
  1574  	return copy.(*ResourceState)
  1575  }
  1576  
  1577  // prune is used to remove any instances that are no longer required
  1578  func (s *ResourceState) prune() {
  1579  	s.Lock()
  1580  	defer s.Unlock()
  1581  
  1582  	n := len(s.Deposed)
  1583  	for i := 0; i < n; i++ {
  1584  		inst := s.Deposed[i]
  1585  		if inst == nil || inst.ID == "" {
  1586  			copy(s.Deposed[i:], s.Deposed[i+1:])
  1587  			s.Deposed[n-1] = nil
  1588  			n--
  1589  			i--
  1590  		}
  1591  	}
  1592  	s.Deposed = s.Deposed[:n]
  1593  
  1594  	s.Dependencies = uniqueStrings(s.Dependencies)
  1595  }
  1596  
  1597  func (s *ResourceState) sort() {
  1598  	s.Lock()
  1599  	defer s.Unlock()
  1600  
  1601  	sort.Strings(s.Dependencies)
  1602  }
  1603  
  1604  func (s *ResourceState) String() string {
  1605  	s.Lock()
  1606  	defer s.Unlock()
  1607  
  1608  	var buf bytes.Buffer
  1609  	buf.WriteString(fmt.Sprintf("Type = %s", s.Type))
  1610  	return buf.String()
  1611  }
  1612  
  1613  // InstanceState is used to track the unique state information belonging
  1614  // to a given instance.
  1615  type InstanceState struct {
  1616  	// A unique ID for this resource. This is opaque to Terraform
  1617  	// and is only meant as a lookup mechanism for the providers.
  1618  	ID string `json:"id"`
  1619  
  1620  	// Attributes are basic information about the resource. Any keys here
  1621  	// are accessible in variable format within Terraform configurations:
  1622  	// ${resourcetype.name.attribute}.
  1623  	Attributes map[string]string `json:"attributes"`
  1624  
  1625  	// Ephemeral is used to store any state associated with this instance
  1626  	// that is necessary for the Terraform run to complete, but is not
  1627  	// persisted to a state file.
  1628  	Ephemeral EphemeralState `json:"-"`
  1629  
  1630  	// Meta is a simple K/V map that is persisted to the State but otherwise
  1631  	// ignored by Terraform core. It's meant to be used for accounting by
  1632  	// external client code. The value here must only contain Go primitives
  1633  	// and collections.
  1634  	Meta map[string]interface{} `json:"meta"`
  1635  
  1636  	// Tainted is used to mark a resource for recreation.
  1637  	Tainted bool `json:"tainted"`
  1638  
  1639  	mu sync.Mutex
  1640  }
  1641  
  1642  func (s *InstanceState) Lock()   { s.mu.Lock() }
  1643  func (s *InstanceState) Unlock() { s.mu.Unlock() }
  1644  
  1645  func (s *InstanceState) init() {
  1646  	s.Lock()
  1647  	defer s.Unlock()
  1648  
  1649  	if s.Attributes == nil {
  1650  		s.Attributes = make(map[string]string)
  1651  	}
  1652  	if s.Meta == nil {
  1653  		s.Meta = make(map[string]interface{})
  1654  	}
  1655  	s.Ephemeral.init()
  1656  }
  1657  
  1658  // NewInstanceStateShimmedFromValue is a shim method to lower a new-style
  1659  // object value representing the attributes of an instance object into the
  1660  // legacy InstanceState representation.
  1661  //
  1662  // This is for shimming to old components only and should not be used in new code.
  1663  func NewInstanceStateShimmedFromValue(state cty.Value, schemaVersion int) *InstanceState {
  1664  	attrs := hcl2shim.FlatmapValueFromHCL2(state)
  1665  	return &InstanceState{
  1666  		ID:         attrs["id"],
  1667  		Attributes: attrs,
  1668  		Meta: map[string]interface{}{
  1669  			"schema_version": schemaVersion,
  1670  		},
  1671  	}
  1672  }
  1673  
  1674  // AttrsAsObjectValue shims from the legacy InstanceState representation to
  1675  // a new-style cty object value representation of the state attributes, using
  1676  // the given type for guidance.
  1677  //
  1678  // The given type must be the implied type of the schema of the resource type
  1679  // of the object whose state is being converted, or the result is undefined.
  1680  //
  1681  // This is for shimming from old components only and should not be used in
  1682  // new code.
  1683  func (s *InstanceState) AttrsAsObjectValue(ty cty.Type) (cty.Value, error) {
  1684  	if s == nil {
  1685  		// if the state is nil, we need to construct a complete cty.Value with
  1686  		// null attributes, rather than a single cty.NullVal(ty)
  1687  		s = &InstanceState{}
  1688  	}
  1689  
  1690  	if s.Attributes == nil {
  1691  		s.Attributes = map[string]string{}
  1692  	}
  1693  
  1694  	// make sure ID is included in the attributes. The InstanceState.ID value
  1695  	// takes precedence.
  1696  	if s.ID != "" {
  1697  		s.Attributes["id"] = s.ID
  1698  	}
  1699  
  1700  	return hcl2shim.HCL2ValueFromFlatmap(s.Attributes, ty)
  1701  }
  1702  
  1703  // Copy all the Fields from another InstanceState
  1704  func (s *InstanceState) Set(from *InstanceState) {
  1705  	s.Lock()
  1706  	defer s.Unlock()
  1707  
  1708  	from.Lock()
  1709  	defer from.Unlock()
  1710  
  1711  	s.ID = from.ID
  1712  	s.Attributes = from.Attributes
  1713  	s.Ephemeral = from.Ephemeral
  1714  	s.Meta = from.Meta
  1715  	s.Tainted = from.Tainted
  1716  }
  1717  
  1718  func (s *InstanceState) DeepCopy() *InstanceState {
  1719  	copy, err := copystructure.Config{Lock: true}.Copy(s)
  1720  	if err != nil {
  1721  		panic(err)
  1722  	}
  1723  
  1724  	return copy.(*InstanceState)
  1725  }
  1726  
  1727  func (s *InstanceState) Empty() bool {
  1728  	if s == nil {
  1729  		return true
  1730  	}
  1731  	s.Lock()
  1732  	defer s.Unlock()
  1733  
  1734  	return s.ID == ""
  1735  }
  1736  
  1737  func (s *InstanceState) Equal(other *InstanceState) bool {
  1738  	// Short circuit some nil checks
  1739  	if s == nil || other == nil {
  1740  		return s == other
  1741  	}
  1742  	s.Lock()
  1743  	defer s.Unlock()
  1744  
  1745  	// IDs must be equal
  1746  	if s.ID != other.ID {
  1747  		return false
  1748  	}
  1749  
  1750  	// Attributes must be equal
  1751  	if len(s.Attributes) != len(other.Attributes) {
  1752  		return false
  1753  	}
  1754  	for k, v := range s.Attributes {
  1755  		otherV, ok := other.Attributes[k]
  1756  		if !ok {
  1757  			return false
  1758  		}
  1759  
  1760  		if v != otherV {
  1761  			return false
  1762  		}
  1763  	}
  1764  
  1765  	// Meta must be equal
  1766  	if len(s.Meta) != len(other.Meta) {
  1767  		return false
  1768  	}
  1769  	if s.Meta != nil && other.Meta != nil {
  1770  		// We only do the deep check if both are non-nil. If one is nil
  1771  		// we treat it as equal since their lengths are both zero (check
  1772  		// above).
  1773  		//
  1774  		// Since this can contain numeric values that may change types during
  1775  		// serialization, let's compare the serialized values.
  1776  		sMeta, err := json.Marshal(s.Meta)
  1777  		if err != nil {
  1778  			// marshaling primitives shouldn't ever error out
  1779  			panic(err)
  1780  		}
  1781  		otherMeta, err := json.Marshal(other.Meta)
  1782  		if err != nil {
  1783  			panic(err)
  1784  		}
  1785  
  1786  		if !bytes.Equal(sMeta, otherMeta) {
  1787  			return false
  1788  		}
  1789  	}
  1790  
  1791  	if s.Tainted != other.Tainted {
  1792  		return false
  1793  	}
  1794  
  1795  	return true
  1796  }
  1797  
  1798  // MergeDiff takes a ResourceDiff and merges the attributes into
  1799  // this resource state in order to generate a new state. This new
  1800  // state can be used to provide updated attribute lookups for
  1801  // variable interpolation.
  1802  //
  1803  // If the diff attribute requires computing the value, and hence
  1804  // won't be available until apply, the value is replaced with the
  1805  // computeID.
  1806  func (s *InstanceState) MergeDiff(d *InstanceDiff) *InstanceState {
  1807  	result := s.DeepCopy()
  1808  	if result == nil {
  1809  		result = new(InstanceState)
  1810  	}
  1811  	result.init()
  1812  
  1813  	if s != nil {
  1814  		s.Lock()
  1815  		defer s.Unlock()
  1816  		for k, v := range s.Attributes {
  1817  			result.Attributes[k] = v
  1818  		}
  1819  	}
  1820  	if d != nil {
  1821  		for k, diff := range d.CopyAttributes() {
  1822  			if diff.NewRemoved {
  1823  				delete(result.Attributes, k)
  1824  				continue
  1825  			}
  1826  			if diff.NewComputed {
  1827  				result.Attributes[k] = hcl2shim.UnknownVariableValue
  1828  				continue
  1829  			}
  1830  
  1831  			result.Attributes[k] = diff.New
  1832  		}
  1833  	}
  1834  
  1835  	return result
  1836  }
  1837  
  1838  func (s *InstanceState) String() string {
  1839  	notCreated := "<not created>"
  1840  
  1841  	if s == nil {
  1842  		return notCreated
  1843  	}
  1844  
  1845  	s.Lock()
  1846  	defer s.Unlock()
  1847  
  1848  	var buf bytes.Buffer
  1849  
  1850  	if s.ID == "" {
  1851  		return notCreated
  1852  	}
  1853  
  1854  	buf.WriteString(fmt.Sprintf("ID = %s\n", s.ID))
  1855  
  1856  	attributes := s.Attributes
  1857  	attrKeys := make([]string, 0, len(attributes))
  1858  	for ak, _ := range attributes {
  1859  		if ak == "id" {
  1860  			continue
  1861  		}
  1862  
  1863  		attrKeys = append(attrKeys, ak)
  1864  	}
  1865  	sort.Strings(attrKeys)
  1866  
  1867  	for _, ak := range attrKeys {
  1868  		av := attributes[ak]
  1869  		buf.WriteString(fmt.Sprintf("%s = %s\n", ak, av))
  1870  	}
  1871  
  1872  	buf.WriteString(fmt.Sprintf("Tainted = %t\n", s.Tainted))
  1873  
  1874  	return buf.String()
  1875  }
  1876  
  1877  // EphemeralState is used for transient state that is only kept in-memory
  1878  type EphemeralState struct {
  1879  	// ConnInfo is used for the providers to export information which is
  1880  	// used to connect to the resource for provisioning. For example,
  1881  	// this could contain SSH or WinRM credentials.
  1882  	ConnInfo map[string]string `json:"-"`
  1883  
  1884  	// Type is used to specify the resource type for this instance. This is only
  1885  	// required for import operations (as documented). If the documentation
  1886  	// doesn't state that you need to set this, then don't worry about
  1887  	// setting it.
  1888  	Type string `json:"-"`
  1889  }
  1890  
  1891  func (e *EphemeralState) init() {
  1892  	if e.ConnInfo == nil {
  1893  		e.ConnInfo = make(map[string]string)
  1894  	}
  1895  }
  1896  
  1897  func (e *EphemeralState) DeepCopy() *EphemeralState {
  1898  	copy, err := copystructure.Config{Lock: true}.Copy(e)
  1899  	if err != nil {
  1900  		panic(err)
  1901  	}
  1902  
  1903  	return copy.(*EphemeralState)
  1904  }
  1905  
  1906  type jsonStateVersionIdentifier struct {
  1907  	Version int `json:"version"`
  1908  }
  1909  
  1910  // Check if this is a V0 format - the magic bytes at the start of the file
  1911  // should be "tfstate" if so. We no longer support upgrading this type of
  1912  // state but return an error message explaining to a user how they can
  1913  // upgrade via the 0.6.x series.
  1914  func testForV0State(buf *bufio.Reader) error {
  1915  	start, err := buf.Peek(len("tfstate"))
  1916  	if err != nil {
  1917  		return fmt.Errorf("Failed to check for magic bytes: %v", err)
  1918  	}
  1919  	if string(start) == "tfstate" {
  1920  		return fmt.Errorf("Terraform 0.7 no longer supports upgrading the binary state\n" +
  1921  			"format which was used prior to Terraform 0.3. Please upgrade\n" +
  1922  			"this state file using Terraform 0.6.16 prior to using it with\n" +
  1923  			"Terraform 0.7.")
  1924  	}
  1925  
  1926  	return nil
  1927  }
  1928  
  1929  // ErrNoState is returned by ReadState when the io.Reader contains no data
  1930  var ErrNoState = errors.New("no state")
  1931  
  1932  // ReadState reads a state structure out of a reader in the format that
  1933  // was written by WriteState.
  1934  func ReadState(src io.Reader) (*State, error) {
  1935  	// check for a nil file specifically, since that produces a platform
  1936  	// specific error if we try to use it in a bufio.Reader.
  1937  	if f, ok := src.(*os.File); ok && f == nil {
  1938  		return nil, ErrNoState
  1939  	}
  1940  
  1941  	buf := bufio.NewReader(src)
  1942  
  1943  	if _, err := buf.Peek(1); err != nil {
  1944  		if err == io.EOF {
  1945  			return nil, ErrNoState
  1946  		}
  1947  		return nil, err
  1948  	}
  1949  
  1950  	if err := testForV0State(buf); err != nil {
  1951  		return nil, err
  1952  	}
  1953  
  1954  	// If we are JSON we buffer the whole thing in memory so we can read it twice.
  1955  	// This is suboptimal, but will work for now.
  1956  	jsonBytes, err := ioutil.ReadAll(buf)
  1957  	if err != nil {
  1958  		return nil, fmt.Errorf("Reading state file failed: %v", err)
  1959  	}
  1960  
  1961  	versionIdentifier := &jsonStateVersionIdentifier{}
  1962  	if err := json.Unmarshal(jsonBytes, versionIdentifier); err != nil {
  1963  		return nil, fmt.Errorf("Decoding state file version failed: %v", err)
  1964  	}
  1965  
  1966  	var result *State
  1967  	switch versionIdentifier.Version {
  1968  	case 0:
  1969  		return nil, fmt.Errorf("State version 0 is not supported as JSON.")
  1970  	case 1:
  1971  		v1State, err := ReadStateV1(jsonBytes)
  1972  		if err != nil {
  1973  			return nil, err
  1974  		}
  1975  
  1976  		v2State, err := upgradeStateV1ToV2(v1State)
  1977  		if err != nil {
  1978  			return nil, err
  1979  		}
  1980  
  1981  		v3State, err := upgradeStateV2ToV3(v2State)
  1982  		if err != nil {
  1983  			return nil, err
  1984  		}
  1985  
  1986  		// increment the Serial whenever we upgrade state
  1987  		v3State.Serial++
  1988  		result = v3State
  1989  	case 2:
  1990  		v2State, err := ReadStateV2(jsonBytes)
  1991  		if err != nil {
  1992  			return nil, err
  1993  		}
  1994  		v3State, err := upgradeStateV2ToV3(v2State)
  1995  		if err != nil {
  1996  			return nil, err
  1997  		}
  1998  
  1999  		v3State.Serial++
  2000  		result = v3State
  2001  	case 3:
  2002  		v3State, err := ReadStateV3(jsonBytes)
  2003  		if err != nil {
  2004  			return nil, err
  2005  		}
  2006  
  2007  		result = v3State
  2008  	default:
  2009  		return nil, fmt.Errorf("Terraform %s does not support state version %d, please update.",
  2010  			tfversion.SemVer.String(), versionIdentifier.Version)
  2011  	}
  2012  
  2013  	// If we reached this place we must have a result set
  2014  	if result == nil {
  2015  		panic("resulting state in load not set, assertion failed")
  2016  	}
  2017  
  2018  	// Prune the state when read it. Its possible to write unpruned states or
  2019  	// for a user to make a state unpruned (nil-ing a module state for example).
  2020  	result.prune()
  2021  
  2022  	// Validate the state file is valid
  2023  	if err := result.Validate(); err != nil {
  2024  		return nil, err
  2025  	}
  2026  
  2027  	return result, nil
  2028  }
  2029  
  2030  func ReadStateV1(jsonBytes []byte) (*stateV1, error) {
  2031  	v1State := &stateV1{}
  2032  	if err := json.Unmarshal(jsonBytes, v1State); err != nil {
  2033  		return nil, fmt.Errorf("Decoding state file failed: %v", err)
  2034  	}
  2035  
  2036  	if v1State.Version != 1 {
  2037  		return nil, fmt.Errorf("Decoded state version did not match the decoder selection: "+
  2038  			"read %d, expected 1", v1State.Version)
  2039  	}
  2040  
  2041  	return v1State, nil
  2042  }
  2043  
  2044  func ReadStateV2(jsonBytes []byte) (*State, error) {
  2045  	state := &State{}
  2046  	if err := json.Unmarshal(jsonBytes, state); err != nil {
  2047  		return nil, fmt.Errorf("Decoding state file failed: %v", err)
  2048  	}
  2049  
  2050  	// Check the version, this to ensure we don't read a future
  2051  	// version that we don't understand
  2052  	if state.Version > StateVersion {
  2053  		return nil, fmt.Errorf("Terraform %s does not support state version %d, please update.",
  2054  			tfversion.SemVer.String(), state.Version)
  2055  	}
  2056  
  2057  	// Make sure the version is semantic
  2058  	if state.TFVersion != "" {
  2059  		if _, err := version.NewVersion(state.TFVersion); err != nil {
  2060  			return nil, fmt.Errorf(
  2061  				"State contains invalid version: %s\n\n"+
  2062  					"Terraform validates the version format prior to writing it. This\n"+
  2063  					"means that this is invalid of the state becoming corrupted through\n"+
  2064  					"some external means. Please manually modify the Terraform version\n"+
  2065  					"field to be a proper semantic version.",
  2066  				state.TFVersion)
  2067  		}
  2068  	}
  2069  
  2070  	// catch any unitialized fields in the state
  2071  	state.init()
  2072  
  2073  	// Sort it
  2074  	state.sort()
  2075  
  2076  	return state, nil
  2077  }
  2078  
  2079  func ReadStateV3(jsonBytes []byte) (*State, error) {
  2080  	state := &State{}
  2081  	if err := json.Unmarshal(jsonBytes, state); err != nil {
  2082  		return nil, fmt.Errorf("Decoding state file failed: %v", err)
  2083  	}
  2084  
  2085  	// Check the version, this to ensure we don't read a future
  2086  	// version that we don't understand
  2087  	if state.Version > StateVersion {
  2088  		return nil, fmt.Errorf("Terraform %s does not support state version %d, please update.",
  2089  			tfversion.SemVer.String(), state.Version)
  2090  	}
  2091  
  2092  	// Make sure the version is semantic
  2093  	if state.TFVersion != "" {
  2094  		if _, err := version.NewVersion(state.TFVersion); err != nil {
  2095  			return nil, fmt.Errorf(
  2096  				"State contains invalid version: %s\n\n"+
  2097  					"Terraform validates the version format prior to writing it. This\n"+
  2098  					"means that this is invalid of the state becoming corrupted through\n"+
  2099  					"some external means. Please manually modify the Terraform version\n"+
  2100  					"field to be a proper semantic version.",
  2101  				state.TFVersion)
  2102  		}
  2103  	}
  2104  
  2105  	// catch any unitialized fields in the state
  2106  	state.init()
  2107  
  2108  	// Sort it
  2109  	state.sort()
  2110  
  2111  	// Now we write the state back out to detect any changes in normaliztion.
  2112  	// If our state is now written out differently, bump the serial number to
  2113  	// prevent conflicts.
  2114  	var buf bytes.Buffer
  2115  	err := WriteState(state, &buf)
  2116  	if err != nil {
  2117  		return nil, err
  2118  	}
  2119  
  2120  	if !bytes.Equal(jsonBytes, buf.Bytes()) {
  2121  		log.Println("[INFO] state modified during read or write. incrementing serial number")
  2122  		state.Serial++
  2123  	}
  2124  
  2125  	return state, nil
  2126  }
  2127  
  2128  // WriteState writes a state somewhere in a binary format.
  2129  func WriteState(d *State, dst io.Writer) error {
  2130  	// writing a nil state is a noop.
  2131  	if d == nil {
  2132  		return nil
  2133  	}
  2134  
  2135  	// make sure we have no uninitialized fields
  2136  	d.init()
  2137  
  2138  	// Make sure it is sorted
  2139  	d.sort()
  2140  
  2141  	// Ensure the version is set
  2142  	d.Version = StateVersion
  2143  
  2144  	// If the TFVersion is set, verify it. We used to just set the version
  2145  	// here, but this isn't safe since it changes the MD5 sum on some remote
  2146  	// state storage backends such as Atlas. We now leave it be if needed.
  2147  	if d.TFVersion != "" {
  2148  		if _, err := version.NewVersion(d.TFVersion); err != nil {
  2149  			return fmt.Errorf(
  2150  				"Error writing state, invalid version: %s\n\n"+
  2151  					"The Terraform version when writing the state must be a semantic\n"+
  2152  					"version.",
  2153  				d.TFVersion)
  2154  		}
  2155  	}
  2156  
  2157  	// Encode the data in a human-friendly way
  2158  	data, err := json.MarshalIndent(d, "", "    ")
  2159  	if err != nil {
  2160  		return fmt.Errorf("Failed to encode state: %s", err)
  2161  	}
  2162  
  2163  	// We append a newline to the data because MarshalIndent doesn't
  2164  	data = append(data, '\n')
  2165  
  2166  	// Write the data out to the dst
  2167  	if _, err := io.Copy(dst, bytes.NewReader(data)); err != nil {
  2168  		return fmt.Errorf("Failed to write state: %v", err)
  2169  	}
  2170  
  2171  	return nil
  2172  }
  2173  
  2174  // resourceNameSort implements the sort.Interface to sort name parts lexically for
  2175  // strings and numerically for integer indexes.
  2176  type resourceNameSort []string
  2177  
  2178  func (r resourceNameSort) Len() int      { return len(r) }
  2179  func (r resourceNameSort) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
  2180  
  2181  func (r resourceNameSort) Less(i, j int) bool {
  2182  	iParts := strings.Split(r[i], ".")
  2183  	jParts := strings.Split(r[j], ".")
  2184  
  2185  	end := len(iParts)
  2186  	if len(jParts) < end {
  2187  		end = len(jParts)
  2188  	}
  2189  
  2190  	for idx := 0; idx < end; idx++ {
  2191  		if iParts[idx] == jParts[idx] {
  2192  			continue
  2193  		}
  2194  
  2195  		// sort on the first non-matching part
  2196  		iInt, iIntErr := strconv.Atoi(iParts[idx])
  2197  		jInt, jIntErr := strconv.Atoi(jParts[idx])
  2198  
  2199  		switch {
  2200  		case iIntErr == nil && jIntErr == nil:
  2201  			// sort numerically if both parts are integers
  2202  			return iInt < jInt
  2203  		case iIntErr == nil:
  2204  			// numbers sort before strings
  2205  			return true
  2206  		case jIntErr == nil:
  2207  			return false
  2208  		default:
  2209  			return iParts[idx] < jParts[idx]
  2210  		}
  2211  	}
  2212  
  2213  	return r[i] < r[j]
  2214  }
  2215  
  2216  // moduleStateSort implements sort.Interface to sort module states
  2217  type moduleStateSort []*ModuleState
  2218  
  2219  func (s moduleStateSort) Len() int {
  2220  	return len(s)
  2221  }
  2222  
  2223  func (s moduleStateSort) Less(i, j int) bool {
  2224  	a := s[i]
  2225  	b := s[j]
  2226  
  2227  	// If either is nil, then the nil one is "less" than
  2228  	if a == nil || b == nil {
  2229  		return a == nil
  2230  	}
  2231  
  2232  	// If the lengths are different, then the shorter one always wins
  2233  	if len(a.Path) != len(b.Path) {
  2234  		return len(a.Path) < len(b.Path)
  2235  	}
  2236  
  2237  	// Otherwise, compare lexically
  2238  	return strings.Join(a.Path, ".") < strings.Join(b.Path, ".")
  2239  }
  2240  
  2241  func (s moduleStateSort) Swap(i, j int) {
  2242  	s[i], s[j] = s[j], s[i]
  2243  }
  2244  
  2245  const stateValidateErrMultiModule = `
  2246  Multiple modules with the same path: %s
  2247  
  2248  This means that there are multiple entries in the "modules" field
  2249  in your state file that point to the same module. This will cause Terraform
  2250  to behave in unexpected and error prone ways and is invalid. Please back up
  2251  and modify your state file manually to resolve this.
  2252  `