Skip to content

Fix bug where -backend-config could not override attributes that weren't at the top level in the backend schema #36919

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

SarahFrench
Copy link
Member

@SarahFrench SarahFrench commented Apr 23, 2025

Fixes #36911

The bug reported in that issue is due to how the code that processes -backend-config flags assumes that any key=value pairs passed in are setting values for a top-level attribute in the backend's schema. The error shared in the fixed GH issue arises due to the code looking for a top-level field with the name assume_role.role_arn instead of looking for role_arn nested within assume_role.

attrS := schema.Attributes[name]
if attrS == nil {
diags = diags.Append(tfdiags.Sourceless(
tfdiags.Error,
"Invalid backend configuration argument",
fmt.Sprintf("The backend configuration argument %q given on the command line is not expected for the selected backend type.", name),
))
continue
}

To enable testing of this update I needed access to a backend with a schema that matches the s3 backend's use of single nesting. Instead of adding a test that uses the s3 backend and needing to supply credentials, I've updated the inmem backend to optionally have an expanded backend for testing purposes. This is controlled by an environment variable specific to that backend. This could be a first step towards considering making the whole inmem backend not user facing and used 100% for tests.

Target Release

1.13.x

CHANGELOG entry

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

@@ -48,19 +50,57 @@ func Reset() {

// New creates a new backend for Inmem remote state.
func New() backend.Backend {
if os.Getenv("TF_INMEM_TEST") != "" {
Copy link
Member Author

Choose a reason for hiding this comment

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

A choice that I needed to consider here was either to:

  • Make the inmem backend have test-specific schemas.
  • Or, add a new in-memory backend that was only available for use in the context of testing.

Currently the inmem backend is available for end users to use if they know it exists (it is not in any docs), but it was intended as a test resource. Making the inmem backend unavailable to end users and only available during tests is a breaking change. We could do that in future, but for now I think making parts of the inmem backend test-only makes sense, instead of creating a new backend that uses 99% of the same code.

Copy link
Member

Choose a reason for hiding this comment

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

I think it'd be great to have this comment somewhere in this code for our future selves.

@SarahFrench SarahFrench marked this pull request as ready for review April 23, 2025 16:08
@SarahFrench SarahFrench requested a review from a team as a code owner April 23, 2025 16:08
dsa0x
dsa0x previously approved these changes Apr 24, 2025
case isNested:
// The flag item is overriding a nested attribute
// e.g. assume_role.role_arn in the s3 backend
// We assume a max nesting-depth of 1 as s3 is the only
Copy link
Member

Choose a reason for hiding this comment

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

Can we somehow bake this assumption in the code validation?

An input like "test_nesting_single.child.grand" was allowed to pass with no error, and the child value ended up being set.


parentName := splitName[0]
nestedName := splitName[1]
parentAttr := schema.Attributes[parentName]
Copy link
Member

Choose a reason for hiding this comment

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

There is a path to panicking here, if the schema does not have parentName

e.g "-backend-config=test_nesting_single_not_exists.child=foobar"

if os.Getenv("TF_INMEM_TEST") != "" {
// We use a different schema for testing. This isn't user facing unless they
// dig into the code.
fmt.Sprintln("TF_INMEM_TEST is set: Using test schema for the inmem backend")
Copy link
Member

Choose a reason for hiding this comment

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

This is using Sprintln, which returns a string, as opposed to printing to the CLI. If that was intentional, then this can simply be a comment.

@@ -48,19 +50,57 @@ func Reset() {

// New creates a new backend for Inmem remote state.
func New() backend.Backend {
if os.Getenv("TF_INMEM_TEST") != "" {
Copy link
Member

Choose a reason for hiding this comment

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

I think it'd be great to have this comment somewhere in this code for our future selves.

@dsa0x dsa0x dismissed their stale review April 24, 2025 06:17

Mistakenly approved

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants