github.com/opentofu/opentofu@v1.7.1/internal/legacy/tofu/state.go (about)

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