terraform-plugin-sdk icon indicating copy to clipboard operation
terraform-plugin-sdk copied to clipboard

Default TypeList / TypeSet

Open iwarapter opened this issue 5 years ago • 5 comments

Terraform provides a test example for using a default for TypeList: https://github.com/hashicorp/terraform/blob/master/helper/schema/schema_test.go#L3624

However if I define one in a provider I get: foo: Default is not valid for lists or sets

I have also tried using a DefaultFunc:

"foo": &schema.Schema{
      Type:     schema.TypeSet,
      Optional: true,
      DefaultFunc: func() (interface{}, error) {
        return []interface{}{"bar", "thing"}, nil
      },
      Elem: &schema.Schema{
        Type: schema.TypeString,
      },
    },

Which compiles but doesn't provide a default, how would you go about achieving this?

Thanks!

iwarapter avatar Mar 15 '19 23:03 iwarapter

Hi, I ran into this problem also.

Do someone have some workaround to this problem?

Thanks.

chkp-idoma avatar Dec 11 '19 09:12 chkp-idoma

Hi, I'm still confused about Default option behavior for Set type. I'd expect if I specify Default option in schema it means the value should be returned by Get()/GetOk() call no matter is it specified in configuration or not.

resource example_box robin {
  bundle = "b-x"
  // "size" attribute of Set type is not specified here
}
func resourceExampleBox() *schema.Resource {
	return &schema.Resource{
		Create: resourceExampleBoxCreate,
...
	"size": {
		Type:     schema.TypeSet,
		Optional: true,
		Elem: &schema.Resource{
			Schema: map[string]*schema.Schema{
				"width": {
					Type:     schema.TypeInt,
					Optional: true,
					Default:  100,
				},
				"height": {
					Type:     schema.TypeInt,
					Optional: true,
					Default:  50,
				},
			},
		},
	},
...
func resourceExampleBoxCreate(d *schema.ResourceData, m interface{}) error {
...
    size := d.Get("size").(*schema.Set).List() // len: 0 here !!! why??? is it a bug or feature?

Here is my discussion with @slapula regarding the subject, but it didn't help me to understand is it a bug or feature. I've also created an example provider to play around and check the unexpected behavior of the defaults.

Tensho avatar Mar 13 '20 22:03 Tensho

I'd also love some clarity on this issue

EliiseS avatar Jun 17 '20 20:06 EliiseS

From my understanding the way that defaults applied to "blocks" such as lists and sets require the block to be declared for it to work.

As you can see in the below example the fields have default env variables and the field is a type list with a max item of one. For the default values to be propagated to the values in the Set/List field it requires you to declare that block.

provider databricks {
host =....
basic_auth {}
}

Without declaring the empty block terraform does not seem to populate default values.

AFAIK you cannot set defaults on the set/list object itself but only the values it contains.

What I cannot confirm is if this is the intended behavior of the sdk/terraform.

Concrete example below:

Provider field definition: https://github.com/databrickslabs/terraform-provider-databricks/blob/c343db6a0c03b98d0f038b8a6c628d3ce2962db9/databricks/provider.go#L69-L89

Usage: https://github.com/databrickslabs/terraform-provider-databricks/blob/c343db6a0c03b98d0f038b8a6c628d3ce2962db9/databricks/resource_databricks_mws_credentials_mws_test.go#L126-L138

stikkireddy avatar Jun 19 '20 11:06 stikkireddy

This also seems to be contrary to what the current documentation for Default says:

Value: any value of an elements Type for primitive types, or the type defined by Elem for complex types. Restrictions:

  • Cannot be used if Required is true
  • Cannot be used with DefaultFunc

If Default is specified, that value that is used when this item is not set in the configuration.

Currently based on this the documentation is just plain wrong 😕

G-Rath avatar Oct 05 '21 00:10 G-Rath