Skip to content

Commit c5fbf2a

Browse files
committed
feat: A plan file will report the state storage provider among its required providers, if PSS is in use.
See the code comment added in this commit. This addition does not impact an apply command as the missing provider will be detected before this code is executed. However I'm making this change so that the method is still accurate is being able to return a complete list of providers needed by the plan.
1 parent 77b45c3 commit c5fbf2a

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed

internal/plans/plan.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,30 @@ func (p *Plan) ProviderAddrs() []addrs.AbsProviderConfig {
181181
}
182182

183183
m := map[string]addrs.AbsProviderConfig{}
184+
185+
// Get all provider requirements from resources.
184186
for _, rc := range p.Changes.Resources {
185187
m[rc.ProviderAddr.String()] = rc.ProviderAddr
186188
}
189+
190+
// Get the provider required for pluggable state storage, if that's in use.
191+
//
192+
// This check should be redundant as:
193+
// 1) Any provider used for state storage would be in required_providers, which is checked separately elsewhere.
194+
// 2) An apply operation that uses the planfile only checks the providers needed for the plan _after_ the operations backend
195+
// for the operation is set up, and that process will detect if the provider needed for state storage is missing.
196+
//
197+
// However, for completeness when describing the providers needed by a plan, it is included here.
198+
if p.StateStore != nil {
199+
address := addrs.AbsProviderConfig{
200+
Module: addrs.RootModule, // A state_store block is only ever in the root module
201+
Provider: *p.StateStore.Provider.Source,
202+
// Alias: aliases are not permitted when using a provider for PSS.
203+
}
204+
205+
m[p.StateStore.Provider.Source.String()] = address
206+
}
207+
187208
if len(m) == 0 {
188209
return nil
189210
}

internal/plans/plan_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,38 @@ import (
99
"github.com/go-test/deep"
1010

1111
"github.com/hashicorp/terraform/internal/addrs"
12+
"github.com/zclconf/go-cty/cty"
1213
)
1314

1415
func TestProviderAddrs(t *testing.T) {
16+
// Inputs for plan
17+
provider := &Provider{}
18+
err := provider.SetSource("registry.terraform.io/hashicorp/pluggable")
19+
if err != nil {
20+
panic(err)
21+
}
22+
err = provider.SetVersion("9.9.9")
23+
if err != nil {
24+
panic(err)
25+
}
26+
config, err := NewDynamicValue(cty.ObjectVal(map[string]cty.Value{
27+
"foo": cty.StringVal("bar"),
28+
}), cty.Object(map[string]cty.Type{
29+
"foo": cty.String,
30+
}))
31+
if err != nil {
32+
panic(err)
33+
}
34+
provider.Config = config
1535

1636
// Prepare plan
1737
plan := &Plan{
38+
StateStore: &StateStore{
39+
Type: "pluggable_foobar",
40+
Provider: provider,
41+
Config: config,
42+
Workspace: "default",
43+
},
1844
VariableValues: map[string]DynamicValue{},
1945
Changes: &ChangesSrc{
2046
Resources: []*ResourceInstanceChangeSrc{
@@ -67,6 +93,11 @@ func TestProviderAddrs(t *testing.T) {
6793
Module: addrs.RootModule,
6894
Provider: addrs.NewDefaultProvider("test"),
6995
},
96+
// Provider used for pluggable state storage
97+
{
98+
Module: addrs.RootModule,
99+
Provider: addrs.NewDefaultProvider("pluggable"),
100+
},
70101
}
71102

72103
for _, problem := range deep.Equal(got, want) {

0 commit comments

Comments
 (0)