Snowflake Terraform Providerの0.95でfully_qualified_nameが導入されて快適に!
最近Snowflake Terraform Providerと戯れているのですが、皆さん新しいバージョンに追従できていますでしょうか?
新しいバージョンに上げるたびに破壊的変更に悩まされて上げるのがおっくうになると思いますが、最近出た0.95へ上げるのは結構モチベーション上がるであろう機能改善が来ておりました!
それは fully_qualified_name というものです↓
何ができるようになったのか
これまではTerraformと戯れているときに特に一番登場するであろうsnowflake_grant_privileges_to_account_role (もしくはdatabase_role版)でリソース名を完全修飾名で入れないといけなくて(マジでエスケープめんどくさい)、依存関係を解決させようと頑張ってリソース参照させたときに1行めっちゃ長くなって、抽象化させてfor_eachで回した日には可読性とはどこへやら...という気持ちになって、メンテナンス性を上げているつもりが、下がってやしないか...?とちょっとした矛盾を抱える日々でした。
今回のアップデートで基本的に必要なリソースにはほぼすべてfully_qualified_nameという完全修飾名が保存される属性が追加されているので、それを参照することができるようになり開発者体験が爆上がりすること間違いなしです(神アプデ!)
サンプルコード
効果が分かりやすいように変数を使いながら抽象化してfor_eachを利用しながらリソースを定義しているようなケースをサンプルコードにしています。
スキーマを用意するついでに権限をセットで用意するようなユースケースです。(READ系の権限が付いたdatabase roleをセットで追加するようなコードです)
terraform {
required_providers {
snowflake = {
source = "Snowflake-Labs/snowflake"
version = "0.95.0"
}
}
}
provider "snowflake" {
# settings ...
}
# Database
resource "snowflake_database" "zenn" {
name = "ZENN_DB"
}
# Schema and Database role
## サンプルとしてスキーマとそのスキーマへのREAD権限を持つDatabase Roleをセットで作るケースを想定(細かいオプションは割愛)
locals {
schemas = {
zenn = {
schema_name = "ZENN"
database = snowflake_database.zenn.name
}
# add another schema
}
}
# Schemas
resource "snowflake_schema" "schemas" {
for_each = local.schemas
name = each.value.schema_name
database = each.value.database
}
# Database roles (READ priviledges on each schema)
resource "snowflake_database_role" "read_on_schema" {
for_each = local.schemas
name = "${each.value.schema_name}__READ"
database = each.value.database
}
# grant USAGE on schema to READ role
resource "snowflake_grant_privileges_to_database_role" "usage_on_schema_to_read_role" {
for_each = local.schemas
database_role_name = snowflake_database_role.read_on_schema["${each.key}"].fully_qualified_name
# 古い書き方だとこうなる
# database_role_name = "\"${snowflake_database_role.read_on_schema["${each.key}"].database}\".\"${snowflake_database_role.read_on_schema["${each.key}"].name}\""
privileges = ["USAGE"]
on_schema {
schema_name = snowflake_schema.schemas["${each.key}"].fully_qualified_name
# 古い書き方だとこうなる
# schema_name = "\"${snowflake_schema.schemas["${each.key}"].database}\".\"${snowflake_schema.schemas["${each.key}"].name}\""
}
}
# grant SELECT on future TABLES in schema to READ role
resource "snowflake_grant_privileges_to_database_role" "select_on_future_tables_in_schema_to_read_role" {
for_each = local.schemas
database_role_name = snowflake_database_role.read_on_schema["${each.key}"].fully_qualified_name
# 古い書き方だとこうなる
# database_role_name = "\"${snowflake_database_role.read_on_schema["${each.key}"].database}\".\"${snowflake_database_role.read_on_schema["${each.key}"].name}\""
privileges = ["SELECT"]
on_schema_object {
future {
object_type_plural = "TABLES"
in_schema = snowflake_schema.schemas["${each.key}"].fully_qualified_name
# 古い書き方だとこうなる
# in_schema = "\"${snowflake_schema.schemas["${each.key}"].database}\".\"${snowflake_schema.schemas["${each.key}"].name}\""
}
}
}
# grant SELECT on future VIEWS in schema to READ role
resource "snowflake_grant_privileges_to_database_role" "select_on_future_views_in_schema_to_read_role" {
for_each = local.schemas
database_role_name = snowflake_database_role.read_on_schema["${each.key}"].fully_qualified_name
# 古い書き方だとこうなる
# database_role_name = "\"${snowflake_database_role.read_on_schema["${each.key}"].database}\".\"${snowflake_database_role.read_on_schema["${each.key}"].name}\""
privileges = ["SELECT"]
on_schema_object {
future {
object_type_plural = "VIEWS"
in_schema = snowflake_schema.schemas["${each.key}"].fully_qualified_name
# 古い書き方だとこうなる
# in_schema = "\"${snowflake_schema.schemas["${each.key}"].database}\".\"${snowflake_schema.schemas["${each.key}"].name}\""
}
}
}
0.94.1まで
こんな具合に長いです。
(VSCodeが間違っているところをハイライトしてくれるからいいものの、サンプルコード書きながら何回修正したことか...一発で誤字脱字もなくこれを書ける人はすごいと思います。マジで\"
がいる意味が分からない)
database_role_name = "\"${snowflake_database_role.read_on_schema["${each.key}"].database}\".\"${snowflake_database_role.read_on_schema["${each.key}"].name}\""
0.95.0だとこう
こうあるべきだよなと思ういい感じの書き方ができるようになりました
database_role_name = snowflake_database_role.read_on_schema["${each.key}"].fully_qualified_name
おまけ
ステートを見るとこんな感じで入っています(特別にdiffでハイライトさせています)
# snowflake_database_role.read_on_schema["zenn"]:
resource "snowflake_database_role" "read_on_schema" {
comment = null
database = "ZENN_DB"
+ fully_qualified_name = "\"ZENN_DB\".\"ZENN__READ\""
id = "\"ZENN_DB\".\"ZENN__READ\""
name = "ZENN__READ"
show_output = [
{
comment = null
created_on = "2024-09-07T20:04:37.592-07:00"
database_name = "ZENN_DB"
granted_database_roles = 0
granted_to_database_roles = 0
granted_to_roles = 0
is_current = false
is_default = false
is_inherited = false
name = "ZENN__READ"
owner = "ACCOUNTADMIN"
owner_role_type = "ROLE"
},
]
}
最後に
なんとなくTerraformを始めるとリソース名を直書きする形で始めてしまい、依存関係うまく解決できなくてリソース追加が一発で成功しないなんてことが皆さんの周りにもあるかと思いますが(特にGrant系は起こりがち)、今後はきっちり依存関係をしっかり解決できるようにdepends_onに頼らない形でコーディングをしやすくなるかなと思います。
神アプデが来て、どんどん使いやすく安定化してきているのでTerraform化していくモチベーションも上がっていきますね。
Discussion