Terraform provides a for_each iterator which allows you to loop over elements of a list, and perform an operation with each element. For example, to grant multiple permissions for myself on a Snowflake schema, I could do something like this:

resource "snowflake_schema_grant" "write_permissions" {
  for_each      = toset(["CREATE TABLE", "CREATE VIEW", "USAGE"])
  database_name = "MY_DATABASE"
  privilege     = each.key
  roles         = "DAVE"
  schema_name   = "MY_SCHEMA"
}

This loops over each element in the for_each list, and substitutes it as the privilege using each.key.

Unfortunately, there is no way in Terraform to to nest this for_each list within another for_each list. Terraform does however support nested loops when creating local data structures, and it has a flatten function which can flatten the resulting list-of-lists. We can combine these two features to create a flat list of objects suitable for use with for_each.

Suppose we have a list of schemas, and I want to give myself a list of permissions on each of them as we did for the MY_SCHEMA schema above:

locals {
  schemas    = [
                 "PRIVATE",
                 "PUBLIC",
                 "MY_SCHEMA",
               ]
  privileges = [
                 "CREATE TABLE",
                 "CREATE VIEW",
                 "USAGE",
               ]

  # Nested loop over both lists, and flatten the result.
  schema_privileges = distinct(flatten([
    for schema in local.schemas : [
      for privilege in local.privileges : {
        privilege = privilege
        schema    = schema
      }
    ]
  ]))
}

This gives us a list of objects with an entry for each operation we want to perform:

[
  { privilege: "CREATE TABLE", schema: "PRIVATE" },
  { privilege: "CREATE VIEW",  schema: "PRIVATE" },
  { privilege: "USAGE",        schema: "PRIVATE" },
  { privilege: "CREATE TABLE", schema: "PUBLIC" },
  { privilege: "CREATE VIEW",  schema: "PUBLIC" },
  { privilege: "USAGE",        schema: "PUBLIC" },
  { privilege: "CREATE TABLE", schema: "MY_SCHEMA" },
  { privilege: "CREATE VIEW",  schema: "MY_SCHEMA" },
  { privilege: "USAGE",        schema: "MY_SCHEMA" },
]

We can then feed this map into for_each to grant the permissions:

resource "snowflake_schema_grant" "write_permissions" {
  # We need a map to use for_each, so we convert our list into a map by adding a unique key:
  for_each      = { for entry in local.schema_privileges: "${entry.schema}.${entry.privilege}" => entry }
  database_name = "MY_DATABASE"
  privilege     = each.value.privilege
  roles         = "DAVE"
  schema_name   = each.value.schema
}