terraform-provider-snowflake icon indicating copy to clipboard operation
terraform-provider-snowflake copied to clipboard

[General Usage]: Why do I need to fully qualify snowflake_grant_privileges_to_account_role.account_role_name?

Open jamiekt opened this issue 6 months ago • 16 comments

Terraform CLI Version

1.9.3

Terraform Provider Version

0.94.1

Terraform Configuration

I have some Snowflake role grants that I want to bring under the control of terraform, so I need to import them. Here is my code:

locals {
   monitor_usage_task_roles = toset([
    data.snowflake_role.MY_ROLE1.name,
    data.snowflake_role.MY_ROLE2.name,
  ])
}
import {
  for_each = local.monitor_usage_task_roles
  to       = snowflake_grant_privileges_to_account_role.monitor_usage_task[each.key]
  id       = "${each.key}|false|false|MONITOR USAGE|OnAccount"
}
resource "snowflake_grant_privileges_to_account_role" "monitor_usage_task" {
  for_each          = local.monitor_usage_task_roles
  privileges        = ["MONITOR USAGE"]
  account_role_name = each.key
  with_grant_option = false
  on_account        = true
}

The resulting plan looks like this for all those roles:

    # snowflake_grant_privileges_to_account_role.monitor_usage_task["MY_ROLE1"] must be replaced
    # (imported from "MY_ROLE1|false|false|MONITOR USAGE|OnAccount")
    # Warning: this will destroy the imported resource
  -/+ resource "snowflake_grant_privileges_to_account_role" "monitor_usage_task" {
        ~ account_role_name = "\"MY_ROLE1\"" -> "MY_ROLE1" # forces replacement
          all_privileges    = false
          always_apply      = false
        ~ id                = "MY_ROLE1|false|false|MONITOR USAGE|OnAccount" -> (known after apply)
          on_account        = true
          privileges        = [
              "MONITOR USAGE",
          ]
          with_grant_option = false
      }

Obviously # Warning: this will destroy the imported resource is very worrying, I definitely don't want to do that.

I note from https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/grant_privileges_to_account_role#import that

All the …_name parts should be fully qualified names (where every part is quoted)

So I change my import block to this (note the new escaped quotes in the id of the import):

import {
  for_each = local.monitor_usage_task_roles
  to       = snowflake_grant_privileges_to_account_role.monitor_usage_task[each.key]
  id       = "\"${each.key}\"|false|false|MONITOR USAGE|OnAccount"
}

The new plan is:

    # snowflake_grant_privileges_to_account_role.monitor_usage_task["MY_ROLE1"] must be replaced
    # (imported from ""MY_ROLE1"|false|false|MONITOR USAGE|OnAccount")
    # Warning: this will destroy the imported resource
  -/+ resource "snowflake_grant_privileges_to_account_role" "monitor_usage_task" {
        ~ account_role_name = "\"MY_ROLE1\"" -> "MY_ROLE1" # forces replacement
          all_privileges    = false
          always_apply      = false
        ~ id                = "\"MY_ROLE1\"|false|false|MONITOR USAGE|OnAccount" -> (known after apply)
          on_account        = true
          privileges        = [
              "MONITOR USAGE",
          ]
          with_grant_option = false
      }

Note the warning, my resource is still going to be destroyed due to the altered account_role_name

Hence I add the same escaping to account_role_name

resource "snowflake_grant_privileges_to_account_role" "monitor_usage_task" {
  for_each          = local.monitor_usage_task_roles
  privileges        = ["MONITOR USAGE"]
  account_role_name = "\"${each.key}\""
  with_grant_option = false
  on_account        = true
}

This time my plan looks better

    # snowflake_grant_privileges_to_account_role.monitor_usage_task["MY_ROLE1"] will be imported
      resource "snowflake_grant_privileges_to_account_role" "monitor_usage_task" {
          account_role_name = "\"MY_ROLE1\""
          all_privileges    = false
          always_apply      = false
          id                = "\"MY_ROLE1\"|false|false|MONITOR USAGE|OnAccount"
          on_account        = true
          privileges        = [
              "MONITOR USAGE",
          ]
          with_grant_option = false
      }

This doesn't feel right though. If I was defining brand new privileges for a role I wouldn't have to wrap account_role_name with escaped quotes, so why do I have to do it when importing? That import block will be removed after the objects are imported so I'm left with escaped quotes around account_role_name with no real reason for them being there (other than they were required for importing). Moreover, I'm concerned that the role refered to when this gets applied will be

  • "MY_ROLE1" as opposed to
  • MY_ROLE1

This seems like a strange stipulation. What is the peculiar circumstance that requires me to use escaped quotes when importing?

Category

category:resource

Object type(s)

resource:grant_privileges_to_account_role

Expected Behavior

I would have expected this code to be sufficient

resource "snowflake_grant_privileges_to_account_role" "monitor_usage_task" {
  for_each          = local.monitor_usage_task_roles
  privileges        = ["MONITOR USAGE"]
  account_role_name = each.key
  with_grant_option = false
  on_account        = true
}

Actual Behavior

I'm required to use

resource "snowflake_grant_privileges_to_account_role" "monitor_usage_task" {
  for_each          = local.monitor_usage_task_roles
  privileges        = ["MONITOR USAGE"]
  account_role_name = "\"${each.key}\""
  with_grant_option = false
  on_account        = true
}

Steps to Reproduce

Create a role in the Snowflake UI Use the code provided above to try to import it

How much impact is this issue causing?

Low

Logs

No response

Additional Information

I don't think so, but if other info is required please let me know

jamiekt avatar Aug 06 '24 17:08 jamiekt