github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/legacy/terraform/state.go (about)

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