Skip to content
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

Attributes inside nested block are not validated #805

Closed
mkuzmin opened this issue Jul 19, 2023 · 7 comments
Closed

Attributes inside nested block are not validated #805

mkuzmin opened this issue Jul 19, 2023 · 7 comments
Assignees
Labels
bug Something isn't working

Comments

@mkuzmin
Copy link

mkuzmin commented Jul 19, 2023

Module version

1.3.2

Terraform Configuration Files

This is an example with official provider to reproduce the issue easier. I get the same behavior with my custom code.

resource "random_id" "server" {
  byte_length = 8
  keepers     = {
    # Unknown attribute
    qwerty = 123
    ami_id = "123"
  }
}

Expected Behavior

Validation should fail:

Error: Unsupported argument
│ 
│   on project.tf line 9, in resource "random_id" "server":
│    9:   qwerty = 123
│ 
│ An argument named "qwerty" is not expected here.

Actual Behavior

Error is ignored:

Terraform will perform the following actions:

  # random_id.server will be created
  + resource "random_id" "server" {
      + b64_std     = (known after apply)
      + b64_url     = (known after apply)
      + byte_length = 8
      + dec         = (known after apply)
      + hex         = (known after apply)
      + id          = (known after apply)
      + keepers     = {
          + "ami_id" = "123"
          + "qwerty" = "123"
        }
    }
@mkuzmin mkuzmin added the bug Something isn't working label Jul 19, 2023
@austinvalle
Copy link
Member

austinvalle commented Jul 19, 2023

Hi there @mkuzmin 👋🏻 !

The random_id.keepers attribute you're referencing in your reproduction doesn't have validation on it's attributes as it's an arbitrary map of string values, represented as MapAttribute of types.StringType.

https://github.com/hashicorp/terraform-provider-random/blob/d62a15b2ba285278698fbf0dde65d8022124c2c8/internal/provider/resource_id.go#L58

I get the same behavior with my custom code.

Can you share the schema and terraform config of your code that you're expecting to produce a validation error? Thanks!

@austinvalle austinvalle added the waiting-response Issues or pull requests waiting for an external response label Jul 19, 2023
@bflad
Copy link
Contributor

bflad commented Jul 19, 2023

Drive-by note to leave some additional breadcrumbs/linking/context: on the Terraform core side of things, https://developer.hashicorp.com/terraform/language/expressions/types#maps-objects is the relevant documentation here. It could potentially use some more verbiage about maps having arbitrary key names while objects have defined attribute names. That change would need to occur upstream. On the provider side of things, https://developer.hashicorp.com/terraform/plugin/framework/handling-data/attributes#map is potentially missing a word like "arbitrary" in front of "string keys". We do have plans to expand the framework type documentation via #695 so its not all colocated on one page and maybe that separation via navigation could help.

@github-actions github-actions bot removed the waiting-response Issues or pull requests waiting for an external response label Jul 19, 2023
@bflad bflad added the waiting-response Issues or pull requests waiting for an external response label Jul 19, 2023
@chrismarget-j
Copy link

I think I've seen the behavior described by @mkuzmin.

In my case, it happens in an object that's nested within a map.

The following terraform config validates okay in spite of bogus_attribute.

terraform {
  required_providers {
    apstra = {
      source  = "Juniper/apstra"
      version = "0.21.0"
    }
  }
}

resource "apstra_rack_type" "r" {
  name                       = "test"
  fabric_connectivity_design = "l3clos"
  leaf_switches = {                    # this is a map
    foo = {                            # foo is the key, but the value at "foo" is an object
      logical_device_id = "ld_id"
      spine_link_speed  = "10G"
      spine_link_count  = 1
      bogus_attribute   = "you betcha" # <= I'd have expected a validation error here
    }
  }
}

@github-actions github-actions bot removed the waiting-response Issues or pull requests waiting for an external response label Jul 19, 2023
@bflad
Copy link
Contributor

bflad commented Jul 20, 2023

One thing we could confirm in @chrismarget-j's case is whether or not those extra keys/attribute names are actually passed across the protocol. They likely are not since Terraform core should be using the provider schema information to build the configuration, proposed new state, and prior state data values that get sent across the protocol. We can try to get this information by setting the TF_LOG_SDK_PROTO_DATA_DIR environment variable and inspecting the ValidateResourceConfig and PlanResourceChange RPC request Config MessagePack data with a tool such as https://github.com/wader/fq.

My hunch though is that this is all behavior on the core side and the issue would need to be filed over there since the provider side likely never even receives those extra keys/attribute names.

For the original case though, @austinvalle's comment above should apply about maps always accepting arbitrary keys.

@asaba-hashi
Copy link

This type of validation is also failing to fail for me with a SingleNestedAttribute:

type Things struct {
	A     types.Bool `tfsdk:"A"`
	B types.Bool `tfsdk:"B"`
}

<snip>

"things": schema.SingleNestedAttribute{
				Attributes: map[string]schema.Attribute{
					"B": schema.BoolAttribute{
						Default:  booldefault.StaticBool(false),
						Optional: true,
						Computed: true,
					},
					"B": schema.BoolAttribute{
						Default:  booldefault.StaticBool(false),
						Optional: true,
						Computed: true,
					},
}
required: true,
}
...

resource "some_resource" "some_resource_name" {

  things = {
     should_fail_to_validate = "but doesn't"
  }
}

@bflad
Copy link
Contributor

bflad commented Jul 24, 2023

I spent a few minutes doing the investigative work mentioned above to check that the extraneous information is not something that is sent across the protocol and it seems to confirm that this is not something we can handle on the provider side of the protocol. Please feel free to double check in your own cases.

Given the following configuration:

resource "framework_schema" "test" {
	single_nested_attribute = {
		single_nested_attribute_attribute = "value1"
		non_existent = "oops" # not in the schema
	}
}

Terraform core is sending only the known schema attribute information across the protocol during the ValidateResourceConfig RPC (e.g. fq -d msgpack tovalue 1690227683787_ValidateResourceConfig_Request_Config.msgpack in my case):

    {
      "key": {
        "length": 23,
        "type": "fixstr",
        "value": "single_nested_attribute"
      },
      "value": {
        "length": 1,
        "pairs": [
          {
            "key": {
              "length": 33,
              "type": "str8",
              "value": "single_nested_attribute_attribute"
            },
            "value": {
              "length": 6,
              "type": "fixstr",
              "value": "value1"
            }
          }
        ],
        "type": "fixmap"
      }
    },

Therefore, it would require an enhancement in Terraform core (which parses the configuration and reads provider schemas) for Terraform to raise any sort of configuration error in these cases. My suggestion would be to file an issue in their issue tracker: https://github.com/hashicorp/terraform/issues

Please find some similar issue references (but nothing that is configuration and provider schema specific) since Terraform's configuration handling behavior of allowing extra object attribute names may be more of a configuration design choice:

@github-actions
Copy link

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.
If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 24, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants