Arbitrary Expressions with Argument Syntax doesn't work

According to the documentation for Arbitrary Expressions with Argument Syntax we should be able to specify blocks like this

# Not recommended, but valid: a constant list-of-objects expression
example = [
  {
    foo = "bar"
  },
  {
    foo = "baz"
  },
]

But this does not seem to work giving error for resource snowflake_warehouse

An argument named “tag” is not expected here. Did you mean to define a block of type “tag”?

resource "snowflake_warehouse" "foo" {
  name = "foo"

  tag = [
    {
      name = "foor"
      value = "bar"
    },
    {
      name = "env"
      value = "dev"
    },
  ]
}

Specifying as blocks works but I am unsure how to do so dynamically (using dynamic block doesn’t seem to work as it only specifies tag block once)

resource "snowflake_warehouse" "foo" {
  name = "foo"

  tag {
    name = "foor"
    value = "bar"
  }

  tag {
    name = "env"
    value = "dev"
  }
}

Any help is appreciated

The error is because there is no attribute called “tag”, as in this case it is a block. For static setups you just repeat the block as many times as you need (assuming the resource supports that) or for dynamic cases you use the dynamic block method.

Dynamic blocks work

locals {
  tags = [
    {
      name = "foo"
      value = "bar"
    },
    {
      name = "env"
      value = "dev"
    },
  ]
}

resource "snowflake_warehouse" "foo" {
  name = "foo"

  dynamic tag {
    for_each = local.tags

    content {
      name = tag.value.name
      value = tag.value.value
    }
  } 
}

I am still not sure why the documentation says we can assign though

That particular documentation page does say:

Rarely, some resource types also support an argument with the same name as a nested block type

and

The information on this page only applies to certain special arguments that were relying on this usage pattern prior to Terraform v0.12.

It depends on the resource. Some accepts a list/map attribute, others expect blocks.