@@ -49,6 +49,20 @@ import (
4949 tfversion "github.com/hashicorp/terraform/version"
5050)
5151
52+ const (
53+ // defaultStateStoreChunkSize is the default chunk size proposed
54+ // to the provider.
55+ // This can be tweaked but should provide reasonable performance
56+ // trade-offs for average network conditions and state file sizes.
57+ defaultStateStoreChunkSize int64 = 8 << 20 // 8 MB
58+
59+ // maxStateStoreChunkSize is the highest chunk size provider may choose
60+ // which we still consider reasonable/safe.
61+ // This reflects terraform-plugin-go's max. RPC message size of 256MB
62+ // and leaves plenty of space for other variable data like diagnostics.
63+ maxStateStoreChunkSize int64 = 128 << 20 // 128 MB
64+ )
65+
5266// BackendOpts are the options used to initialize a backendrun.OperationsBackend.
5367type BackendOpts struct {
5468 // BackendConfig is a representation of the backend configuration block given in
@@ -2127,7 +2141,6 @@ func (m *Meta) stateStoreInitFromConfig(c *configs.StateStore, opts *BackendOpts
21272141 configureResp := provider .ConfigureProvider (providers.ConfigureProviderRequest {
21282142 TerraformVersion : tfversion .String (),
21292143 Config : providerConfigVal ,
2130- // TODO ClientCapabilities?
21312144 })
21322145 diags = diags .Append (configureResp .Diagnostics )
21332146 if configureResp .Diagnostics .HasErrors () {
@@ -2149,12 +2162,32 @@ func (m *Meta) stateStoreInitFromConfig(c *configs.StateStore, opts *BackendOpts
21492162 cfgStoreResp := provider .ConfigureStateStore (providers.ConfigureStateStoreRequest {
21502163 TypeName : c .Type ,
21512164 Config : stateStoreConfigVal ,
2165+ Capabilities : providers.StateStoreClientCapabilities {
2166+ ChunkSize : defaultStateStoreChunkSize ,
2167+ },
21522168 })
21532169 diags = diags .Append (cfgStoreResp .Diagnostics )
21542170 if cfgStoreResp .Diagnostics .HasErrors () {
21552171 return nil , cty .NilVal , cty .NilVal , diags
21562172 }
21572173
2174+ chunkSize := cfgStoreResp .Capabilities .ChunkSize
2175+ if chunkSize > maxStateStoreChunkSize {
2176+ diags = diags .Append (fmt .Errorf ("Failed to negotiate acceptable chunk size. " +
2177+ "Expected size <= %d bytes, provider wants %d bytes" ,
2178+ maxStateStoreChunkSize , chunkSize ,
2179+ ))
2180+ return nil , cty .NilVal , cty .NilVal , diags
2181+ }
2182+
2183+ p , ok := provider .(providers.StateStoreChunkSizeSetter )
2184+ if ! ok {
2185+ msg := fmt .Sprintf ("Unable to set chunk size for provider %s; this is a bug in Terraform - please report it" , c .Type )
2186+ panic (msg )
2187+ }
2188+ // casting to int here is okay because the number should never exceed int32
2189+ p .SetStateStoreChunkSize (c .Type , int (chunkSize ))
2190+
21582191 // Now we have a fully configured state store, ready to be used.
21592192 // To make it usable we need to return it in a backend.Backend interface.
21602193 b , err := backendPluggable .NewPluggable (provider , c .Type )
0 commit comments