Skip to content

Conversation

SarahFrench
Copy link
Member

This PR allows the experimental PSS version of init logic recognise when there have been no changes since the last init, so init will perform a no-op (in regards to state storage, at least).

I've added a test showing that init is a no-op in those circumstances : TestInit_stateStore_configUnchanged

I've also added tests showing that when backend state and config don't match we hit a not configured yet error diagnostic - see TestInit_stateStore_configChanges. To do this I've created sets of test fixtures where the backend state file and config are not in agreement. A special case of this, upgraded provider versions, is in TestInit_stateStore_providerUpgrade.

Changes covered:

  • state_store config changed - internal/command/testdata/state-store-changed/store-config
  • provider config changed - internal/command/testdata/state-store-changed/provider-config
  • state_store type changed - internal/command/testdata/state-store-changed/state-store-type
  • provider used for PSS changed - internal/command/testdata/state-store-changed/provider-used
  • provider upgraded - internal/command/testdata/state-store-changed/provider-upgraded

Target Release

N/A

Rollback Plan

  • If a change needs to be reverted, we will roll out an update to the code within 7 days.

Changes to Security Controls

Are there any changes to security controls (access controls, encryption, logging) in this pull request? If so, explain.

CHANGELOG entry

  • This change is user-facing and I added a changelog entry.
  • This change is not user-facing.

…iltin and re-attached providers.

This makes comparison easier when determining if config has changed since last init.
…a change, but handling this scenario isn't implemented yet
Previously dummy values were fine, but as tests using hashes to identify changes these values need to be accurate!
…der version as described in the backend state file fixture for the test.
…as a change, but handling this scenario isn't implemented yet
…ation in the same provider is detected as a change, but handling this scenario isn't implemented yet
…as a change, but handling this scenario isn't implemented yet
…ut handling this scenario isn't implemented yet
Just to avoid any confusion if copy-pasting happens in future.
…ull, and replace dummy hash values with correct values.
@SarahFrench SarahFrench added the no-changelog-needed Add this to your PR if the change does not require a changelog entry label Oct 15, 2025
@SarahFrench SarahFrench marked this pull request as ready for review October 15, 2025 17:08
@SarahFrench SarahFrench requested a review from a team as a code owner October 15, 2025 17:08
radeksimko
radeksimko previously approved these changes Oct 17, 2025
Comment on lines 16 to 18
"hash": 2116468040
},
"hash": 2116468040
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a random observation - not a blocker - how is it that these two hashes match exactly? I thought that each hash represents a different part of the configuration, so should differ?

Copy link
Member Author

@SarahFrench SarahFrench Oct 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it's odd, but I double checked and the values are correct.

Using a debugger I found an explanation for why they match. To get hashes of the state_store and provider configs we use the (cty.Value) Hash method (used here in Core code). The (cty.Value) Hash method iterates through values to create a slice of bytes which are used to create the final hash number. The process of building those bytes for the hashes in this use case hits this code, which ignore the names of keys and only use values.

The end result is that, because both the state store and provider have 1 attr with the value "foobar", the bytes used to make the hash in both cases is:

"<"test_store";<"foobar";>;>"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I'm half correct - the tuple is constructed in our calling code so we can make the hashes be distinct:

pToHash := cty.TupleVal([]cty.Value{
cty.StringVal(b.Type),
pVal,
})

Copy link
Member Author

@SarahFrench SarahFrench Oct 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should address this, but in a separate PR

Edit: I've since changed this opinion, after we agreed that we should swap to a single hash for the whole state_store block in this discussion.

Copy link
Member Author

@SarahFrench SarahFrench Oct 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All commits following this thread, barring removing unused code, are related to this thread.

… impacted by: state store config, provider config, state store type, provider source
@SarahFrench
Copy link
Member Author

Ah there are still issues...go vet failed me

Comment on lines +207 to +215
toHash := cty.TupleVal([]cty.Value{
cty.StringVal(b.Type), // state store type
ssVal, // state store config

cty.StringVal(b.ProviderAddr.String()), // provider source
cty.StringVal(stateStoreProviderVersion.String()), // provider version
cty.StringVal(b.Provider.Name), // provider name - this is directly parsed from the config, whereas provider source is added separately later after config is parsed.
pVal, // provider config
})
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Behold the beautiful new hash contents ✨

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-changelog-needed Add this to your PR if the change does not require a changelog entry

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants