@@ -66,6 +66,10 @@ type BackendOpts struct {
6666 // version in use currently.
6767 Locks * depsfile.Locks
6868
69+ // PreviousLocks allows state-migration logic to use the older version of the provider
70+ // during upgrade-triggered migrations.
71+ PreviousLocks * depsfile.Locks
72+
6973 // ConfigOverride is an hcl.Body that, if non-nil, will be used with
7074 // configs.MergeBodies to override the type-specific backend configuration
7175 // arguments in Config.
@@ -1049,7 +1053,7 @@ func (m *Meta) backendFromConfig(opts *BackendOpts) (backend.Backend, tfdiags.Di
10491053 v := views .NewInit (opts .ViewType , m .View )
10501054 v .Output (views .InitMessageCode ("state_store_unset" ), s .StateStore .Type )
10511055
1052- return m .stateStore_to_backend (sMgr , "local" , localB , nil , opts . ViewType )
1056+ return m .stateStore_to_backend (sMgr , "local" , localB , nil , opts )
10531057
10541058 // Configuring a backend for the first time or -reconfigure flag was used
10551059 case backendConfig != nil && s .Backend .Empty () &&
@@ -1123,7 +1127,7 @@ func (m *Meta) backendFromConfig(opts *BackendOpts) (backend.Backend, tfdiags.Di
11231127 newBackendCfgState .SetConfig (configVal , b .ConfigSchema ())
11241128 newBackendCfgState .Hash = uint64 (cHash )
11251129
1126- return m .stateStore_to_backend (sMgr , backendConfig .Type , b , newBackendCfgState , opts . ViewType )
1130+ return m .stateStore_to_backend (sMgr , backendConfig .Type , b , newBackendCfgState , opts )
11271131
11281132 // Migration from backend to state store
11291133 case backendConfig == nil && ! s .Backend .Empty () &&
@@ -1225,7 +1229,7 @@ func (m *Meta) backendFromConfig(opts *BackendOpts) (backend.Backend, tfdiags.Di
12251229 // AND we're not providing any overrides. An override can mean a change overriding an unchanged backend block (indicated by the hash value).
12261230 if (uint64 (cHash ) == s .StateStore .Hash ) && (! opts .Init || opts .ConfigOverride == nil ) {
12271231 log .Printf ("[TRACE] Meta.Backend: using already-initialized, unchanged %q state_store configuration" , stateStoreConfig .Type )
1228- savedStateStore , sssDiags := m .savedStateStore (sMgr )
1232+ savedStateStore , sssDiags := m .savedStateStore (sMgr , opts . Locks )
12291233 diags = diags .Append (sssDiags )
12301234 // Verify that selected workspace exist. Otherwise prompt user to create one
12311235 if opts .Init && savedStateStore != nil {
@@ -1243,7 +1247,7 @@ func (m *Meta) backendFromConfig(opts *BackendOpts) (backend.Backend, tfdiags.Di
12431247 // don't need to migrate, we update the state store cache hash value.
12441248 if ! m .stateStoreConfigNeedsMigration (stateStoreConfig , s .StateStore , opts ) {
12451249 log .Printf ("[TRACE] Meta.Backend: using already-initialized %q state store configuration" , stateStoreConfig .Type )
1246- savedStateStore , moreDiags := m .savedStateStore (sMgr )
1250+ savedStateStore , moreDiags := m .savedStateStore (sMgr , opts . Locks )
12471251 diags = diags .Append (moreDiags )
12481252 if moreDiags .HasErrors () {
12491253 return nil , diags
@@ -1448,7 +1452,7 @@ func (m *Meta) determineStateStoreInitReason(cfgState *workdir.StateStoreConfigS
14481452// from the backend state. This should be used only when a user runs
14491453// `terraform init -backend=false`. This function returns a local backend if
14501454// there is no backend state or no backend configured.
1451- func (m * Meta ) backendFromState (_ context.Context ) (backend.Backend , tfdiags.Diagnostics ) {
1455+ func (m * Meta ) backendFromState (_ context.Context , locks * depsfile. Locks ) (backend.Backend , tfdiags.Diagnostics ) {
14521456 var diags tfdiags.Diagnostics
14531457 // Get the path to where we store a local cache of backend configuration
14541458 // if we're using a remote backend. This may not yet exist which means
@@ -1474,7 +1478,7 @@ func (m *Meta) backendFromState(_ context.Context) (backend.Backend, tfdiags.Dia
14741478 // state_store
14751479 log .Printf ("[TRACE] Meta.Backend: working directory was previously initialized for %q state store" , s .StateStore .Type )
14761480 var ssDiags tfdiags.Diagnostics
1477- b , ssDiags = m .savedStateStore (sMgr ) // Relies on the state manager's internal state being refreshed above.
1481+ b , ssDiags = m .savedStateStore (sMgr , locks ) // Relies on the state manager's internal state being refreshed above.
14781482 diags = diags .Append (ssDiags )
14791483 if ssDiags .HasErrors () {
14801484 return nil , diags
@@ -2523,17 +2527,17 @@ func (m *Meta) stateStore_C_s(c *configs.StateStore, stateStoreHash int, backend
25232527}
25242528
25252529// Migrating a state store to backend (including local).
2526- func (m * Meta ) stateStore_to_backend (ssSMgr * clistate.LocalState , dstBackendType string , dstBackend backend.Backend , newBackendState * workdir.BackendConfigState , viewType arguments. ViewType ) (backend.Backend , tfdiags.Diagnostics ) {
2530+ func (m * Meta ) stateStore_to_backend (ssSMgr * clistate.LocalState , dstBackendType string , dstBackend backend.Backend , newBackendState * workdir.BackendConfigState , opts * BackendOpts ) (backend.Backend , tfdiags.Diagnostics ) {
25272531 var diags tfdiags.Diagnostics
25282532
25292533 s := ssSMgr .State ()
25302534 stateStoreType := s .StateStore .Type
25312535
2532- view := views .NewInit (viewType , m .View )
2536+ view := views .NewInit (opts . ViewType , m .View )
25332537 view .Output (views .StateMigrateLocalMessage , stateStoreType )
25342538
25352539 // Initialize the configured state store
2536- ss , moreDiags := m .savedStateStore (ssSMgr )
2540+ ss , moreDiags := m .savedStateStore (ssSMgr , opts . Locks )
25372541 diags = diags .Append (moreDiags )
25382542 if moreDiags .HasErrors () {
25392543 return nil , diags
@@ -2545,7 +2549,7 @@ func (m *Meta) stateStore_to_backend(ssSMgr *clistate.LocalState, dstBackendType
25452549 DestinationType : dstBackendType ,
25462550 Source : ss ,
25472551 Destination : dstBackend ,
2548- ViewType : viewType ,
2552+ ViewType : opts . ViewType ,
25492553 })
25502554 if err != nil {
25512555 diags = diags .Append (err )
@@ -2660,7 +2664,7 @@ func (m *Meta) stateStore_changed(cfg *configs.StateStore, cfgHash int, sMgr *cl
26602664 }
26612665
26622666 // Grab the source state store
2663- srcB , srcBDiags := m .savedStateStore (sMgr )
2667+ srcB , srcBDiags := m .savedStateStore (sMgr , opts . PreviousLocks )
26642668 diags = diags .Append (srcBDiags )
26652669 if srcBDiags .HasErrors () {
26662670 return nil , diags
@@ -2843,7 +2847,7 @@ func (m *Meta) createDefaultWorkspace(c *configs.StateStore, b backend.Backend)
28432847}
28442848
28452849// Initializing a saved state store from the backend state file (aka 'cache file', aka 'legacy state file')
2846- func (m * Meta ) savedStateStore (sMgr * clistate.LocalState ) (backend.Backend , tfdiags.Diagnostics ) {
2850+ func (m * Meta ) savedStateStore (sMgr * clistate.LocalState , locks * depsfile. Locks ) (backend.Backend , tfdiags.Diagnostics ) {
28472851 // We're preparing a state_store version of backend.Backend.
28482852 //
28492853 // The provider and state store will be configured using the backend state file.
@@ -2852,7 +2856,7 @@ func (m *Meta) savedStateStore(sMgr *clistate.LocalState) (backend.Backend, tfdi
28522856
28532857 s := sMgr .State ()
28542858
2855- factory , pDiags := m .StateStoreProviderFactoryFromConfigState (s .StateStore )
2859+ factory , pDiags := m .StateStoreProviderFactoryFromConfigState (s .StateStore , locks )
28562860 diags = diags .Append (pDiags )
28572861 if pDiags .HasErrors () {
28582862 return nil , diags
@@ -3366,7 +3370,7 @@ func (m *Meta) StateStoreProviderFactoryFromConfig(config *configs.StateStore, l
33663370 return factory , diags
33673371}
33683372
3369- func (m * Meta ) StateStoreProviderFactoryFromConfigState (cfgState * workdir.StateStoreConfigState ) (providers.Factory , tfdiags.Diagnostics ) {
3373+ func (m * Meta ) StateStoreProviderFactoryFromConfigState (cfgState * workdir.StateStoreConfigState , locks * depsfile. Locks ) (providers.Factory , tfdiags.Diagnostics ) {
33703374 var diags tfdiags.Diagnostics
33713375
33723376 if cfgState == nil {
@@ -3382,7 +3386,7 @@ func (m *Meta) StateStoreProviderFactoryFromConfigState(cfgState *workdir.StateS
33823386 })
33833387 }
33843388
3385- factories , err := m .ProviderFactories ( )
3389+ factories , err := m .providerFactoriesFromLocks ( locks )
33863390 if err != nil {
33873391 // This may happen if the provider isn't present in the provider cache.
33883392 // This should be caught earlier by logic that diffs the config against the backend state file.
0 commit comments