
terraform-provider-snowflakeをv0.88.0からv2.0.0にアップグレードしてみた
さがらです。
terraform-provider-snowflakeをv0.88.0からv2.0.0にアップグレードしてみたので、その時の内容を本記事でまとめてみます。
前提条件
terraformの実行環境は以下の2環境に分けていて、dev/prodでSnowflakeアカウントを2つに分けて管理しており、stateも2つに分けて管理しています。
- dev:terraformの開発用環境。新規開発・変更を柔軟に行いローカルから
terraform apply
まで試せる環境 - prod:本番用の環境。dev環境で上手くapplyまでできた内容を元にprodフォルダのmain.tfの内容を更新し、prodのmainブランチに対してプルリクエスト発行した際に
terraform plan
が実行され、mainブランチにマージされたらterraform apply
されるようにCI/CDを組んでいる
terraformを実行しているリポジトリの構成は下記です。1年前に執筆した以下のブログをベースとして、environments
フォルダでdev
とprod
を分けた構成になっています。
注意点として、データベース・スキーマ・ウェアハウス・ロール・ユーザー、のresourceしか使っていないリポジトリです。その他のresourceのアップグレード対応については確認できておりません。
.
├── README.md
├── cfn
│ └── create_state_gha_resources.yaml
├── environments
│ ├── dev
│ │ ├── backend.tf
│ │ ├── main.tf
│ │ ├── output.tf
│ │ ├── terraform.tfvars
│ │ ├── variables.tf
│ │ └── versions.tf
│ └── prod
│ ├── backend.tf
│ ├── main.tf
│ ├── output.tf
│ ├── terraform.tfvars
│ ├── variables.tf
│ └── versions.tf
└── modules
├── access_role_and_database
│ ├── main.tf
│ ├── output.tf
│ ├── variables.tf
│ └── versions.tf
├── access_role_and_schema
│ ├── main.tf
│ ├── output.tf
│ ├── variables.tf
│ └── versions.tf
├── access_role_and_warehouse
│ ├── main.tf
│ ├── output.tf
│ ├── variables.tf
│ └── versions.tf
├── functional_role
│ ├── main.tf
│ ├── output.tf
│ ├── variables.tf
│ └── versions.tf
└── user
├── main.tf
├── output.tf
├── variables.tf
└── versions.tf
アップグレード手順
バージョンは1つ1つマイナーバージョンをアップグレードしながらdev環境でapplyまで行い、その後にprod環境のコードも修正してコミットし、プルリクエストを発行してCI/CDでprod環境に反映させていきます。
- ブランチを切る
- prodフォルダの
main.tf
を、devフォルダのmain.tf
へコピーし、terraform plan
→terraform apply
を実行(prodと同じリソース構成でちゃんとバージョンアップが出来るかを確認するため) - devフォルダと各modulesフォルダの
versions.tf
の内容を1つアップグレードする
a.version = "0.88.0"
だったら、version = "0.89.0"
に書き換える - devフォルダで
terraform init -upgrade
⇛terraform plan
→terraform apply
を実行
a. diffやエラーが出たら、「各種resourceのプロパティの記述を変更」、「removed block、import block、などを使ってresourceを移行」など必要な対処を行い、terraform plan
→terraform apply
をエラーがなくなるまで繰り返す
b. 変更内容によっては、適時environments/dev/main.tf
も修正する - prodフォルダの
versions.tf
の内容を1つアップグレードし、必要に応じてenvironments/prod/main.tf
も修正して、prodフォルダでterraform init -upgrade
⇛terraform plan
を実行する。問題なさそうであれば、プルリクエスト発行→マージする(前提条件にも書いたように、マージされたタイミングでprod環境に対してterraform apply
が実行される)
GitHubのリポジトリではMigration Guideも公開されていますので、こちらも参考にどういった変更が行われているかを確認しながらアップグレードしていきましょう。
上述の手順を考えるにあたっては、以下の記事も非常に参考にさせていただきました。
v0.88.0→v0.89.0へのアップグレード
Migration Guide
主なアップグレード時の修正内容
特に問題なく、versionを上げるだけでアップグレード出来ました。
v0.89.0⇛v0.90.0へのアップグレード
Migration Guide
主なアップグレード時の修正内容
特に問題なく、versionを上げるだけでアップグレード出来ました。
v0.90.0⇛v0.91.0へのアップグレード
Migration Guide
存在しませんでした。
主なアップグレード時の修正内容
特に問題なく、versionを上げるだけでアップグレード出来ました。
v0.91.0⇛v0.92.0へのアップグレード
Migration Guide
存在しませんでした。
主なアップグレード時の修正内容
特に問題なく、versionを上げるだけでアップグレード出来ました。
v0.92.0⇛v0.93.0へのアップグレード
Migration Guide
主なアップグレード時の修正内容
特に問題なく、versionを上げるだけでアップグレード出来ましたが、terraform plan
の実行時にウェアハウスのリソースについて以下のメッセージが出てきました。
内容としては、ウェアハウスに関するQuery Acceleration Serviceなどのデフォルト値が設定されたため、それに伴い変更があったことを意味しています。(参考)
# module.bbb_develop_wh.snowflake_warehouse.this will be updated in-place
~ resource "snowflake_warehouse" "this" {
~ enable_query_acceleration = "false" -> "default"
id = "BBB_DEVELOP_WH"
~ max_concurrency_level = 8 -> (known after apply)
name = "BBB_DEVELOP_WH"
~ query_acceleration_max_scale_factor = 8 -> -1
- scaling_policy = "STANDARD" -> null
~ show_output = [
- {
- auto_resume = true
- auto_suspend = 60
- available = 0
- comment = "Warehouse for develop of BBB projects"
- created_on = "2025-04-10 17:03:45.405 -0700 PDT"
- enable_query_acceleration = false
- is_current = false
- is_default = false
- max_cluster_count = 1
- min_cluster_count = 1
- name = "BBB_DEVELOP_WH"
- other = 0
- owner = "TERRAFORM"
- owner_role_type = "ROLE"
- provisioning = 0
- query_acceleration_max_scale_factor = 8
- queued = 0
- quiescing = 0
- resumed_on = "2025-04-10 17:03:45.405 -0700 PDT"
- running = 0
- scaling_policy = "STANDARD"
- size = "XSMALL"
- started_clusters = 0
- state = "SUSPENDED"
- type = "STANDARD"
- updated_on = "2025-04-10 17:03:45.429 -0700 PDT"
# (1 unchanged attribute hidden)
},
] -> (known after apply)
~ statement_queued_timeout_in_seconds = 0 -> (known after apply)
~ statement_timeout_in_seconds = 172800 -> (known after apply)
# (9 unchanged attributes hidden)
v0.93.0⇛v0.94.0へのアップグレード
Migration Guide
主なアップグレード時の修正内容
snowflake_schema
の引数の名称変更
エラー:terraform plan
実行時に以下のエラーが起きました。
│ Error: Unsupported argument
│
│ on ../../modules/access_role_and_schema/main.tf line 6, in resource "snowflake_schema" "this":
│ 6: data_retention_days = var.data_retention_days
│
│ An argument named "data_retention_days" is not expected here.
╵
╷
│ Error: Unsupported argument
│
│ on ../../modules/access_role_and_schema/main.tf line 8, in resource "snowflake_schema" "this":
│ 8: is_managed = var.is_managed
│
│ An argument named "is_managed" is not expected here.
原因は、data_retention_days
とis_managed
が、それぞれdata_retention_time_in_days
とwith_managed_access
に名称変更されたことです。
このため、以下のコマンドで修正を行いました。
.tf
ファイルで対象の引数の名称置換:実行時のカレントディレクトリ配下の.tfファイルすべてが対象となるため注意
find . -type f -name "*.tf" -exec sed -i 's/data_retention_days/data_retention_time_in_days/g' {} +
find . -type f -name "*.tf" -exec sed -i 's/is_managed/with_managed_access/g' {} +
snowflake_role
の廃止とsnowflake_account_role
への移行
警告:terraform plan
実行時に以下の警告が出てきました。
╷
│ Warning: Deprecated Resource
│
│ with module.aaa_develop_wh.snowflake_role.usage_ar,
│ on ../../modules/access_role_and_warehouse/main.tf line 23, in resource "snowflake_role" "usage_ar":
│ 23: resource "snowflake_role" "usage_ar" {
│
│ This resource is deprecated and will be removed in a future major version release. Please use
│ snowflake_account_role instead.
│
│ (and 23 more similar warnings elsewhere)
原因はsnowflake_role
のresourceが廃止されるので、snowflake_account_role
のリソースを使おう、という内容になります。
対策として、以下の手順で修正を行いました。
snowflake_role
でstateに登録されている一覧を確認
terraform state list | grep snowflake_role
-
snowflake_role
で実際にSnowflake上で管理されていたロールの一覧を確認- 私はCursorで雑に「対象の全ロールの名称の確認をしてください」とやったら、各
.tf
ファイルを解析してもらい、一覧を出してもらえました…
- 私はCursorで雑に「対象の全ロールの名称の確認をしてください」とやったら、各
-
.tf
ファイルで対象のresourceの名称置換:実行時のカレントディレクトリ配下の.tfファイルすべてが対象となるため注意
find . -type f -name "*.tf" -exec sed -i 's/snowflake_role/snowflake_account_role/g' {} +
- removed blockで古い
snowflake_role
のmoduleをremoveし、import blockで新しいsnowflake_account_role
を用いたmoduleをimportする
# module:functional_roleの場合
module "aaa_developer_fr" {
source = "../../modules/functional_role"
providers = {
snowflake = snowflake.terraform
}
role_name = "AAA_DEVELOPER_FR"
grant_user_set = [
module.developer_sagara.name
]
comment = "Functional Role for develop in Project AAA"
}
removed {
from = module.aaa_developer_fr.snowflake_role.this
lifecycle {
destroy = false
}
}
import {
to = module.aaa_developer_fr.snowflake_account_role.this
id = "AAA_DEVELOPER_FR"
}
# module:access_role_and_warehouseの場合
module "aaa_develop_wh" {
source = "../../modules/access_role_and_warehouse"
providers = {
snowflake = snowflake.terraform
}
warehouse_name = "AAA_DEVELOP_WH"
warehouse_size = "XSMALL"
comment = "Warehouse for develop of AAA projects"
grant_admin_ar_to_fr_set = [
module.aaa_developer_fr.name
]
}
removed {
from = module.aaa_develop_wh.snowflake_role.usage_ar
lifecycle {
destroy = false
}
}
import {
to = module.aaa_develop_wh.snowflake_account_role.usage_ar
id = "_WAREHOUSE_AAA_DEVELOP_WH_USAGE_AR"
}
removed {
from = module.aaa_develop_wh.snowflake_role.admin_ar
lifecycle {
destroy = false
}
}
import {
to = module.aaa_develop_wh.snowflake_account_role.admin_ar
id = "_WAREHOUSE_AAA_DEVELOP_WH_ADMIN_AR"
}
- 上記の設定を行った上で
terraform plan
を実行すると、下図のようにn to import
と表示される
terraform apply
を行い、removeとimportの処理を実施
v0.94.0⇛v0.95.0へのアップグレード
Migration Guide
主なアップグレード時の修正内容
エラー:snowflake_userの引数の名称変更
terraform plan
実行時に以下のエラーが起きました。
╷
│ Error: Unsupported argument
│
│ on ../../modules/user/main.tf line 13, in resource "snowflake_user" "this":
│ 13: default_secondary_roles = var.default_secondary_roles
│
│ An argument named "default_secondary_roles" is not expected here.
╵
原因は、default_secondary_roles
が、default_secondary_roles_option
に名称変更されてstring型に変更されたことです。
このため、以下の手順で修正を行いました。
.tf
ファイルで対象の引数の名称置換:実行時のカレントディレクトリ配下の.tfファイルすべてが対象となるため注意
find . -type f -name "*.tf" -exec sed -i 's/default_secondary_roles/default_secondary_roles_option/g' {} +
- module:userの
variables.tf
の中で、default_secondary_roles_option
を以下の内容に変更
variable "default_secondary_roles_option" {
description = "Specifies the set of secondary roles that are active for the user’s session upon login. Currently only [ALL] value is supported"
type = string
default = "NONE"
}
エラー:identifier(識別子)の仕様変更 ※v0.95.0では未解決
上記のエラー解消後にterraform plan
を再度実行すると、以下のエラーが起きました。
╷
│ Error: sql: Scan error on column index 14, name "default_namespace": converting NULL to string is unsupported
│
│ with module.analyst_sagara.snowflake_user.this,
│ on ../../modules/user/main.tf line 1, in resource "snowflake_user" "this":
│ 1: resource "snowflake_user" "this" {
│
╵
原因は、Snowflake Provider v0.95.0でidentifier(識別子)の仕様変更があったためです。(詳細)
しかし、「全てのstring型の変数のデフォルト値を""
に変更」、「default_namespace = ""
をmoduleでもmodule呼び出し側でも追加」、など色々なことをやってもこのエラーは解消しませんでした…
その上で調べると、以下のIssueに記載のあるバグを踏んでいると感じました。既にバンドル2024_08はデフォルトで有効化されていましたので…。
そのため、このIssueに沿って、バージョンをv0.98.0にアップグレードして対応することにしました。
v0.95.0⇛v0.98.0へのアップグレード
Migration Guide
※v0.97.0⇛v0.98.0のMigration Guideへのリンクとなります
主なアップグレード時の修正内容
エラー:identifier(識別子)の仕様変更 ※v0.95.0ではバンドル2024_08に対応しておらず未解決だったもの
このエラーはv0.98.0にすることで、このエラーは出なくなりました!
disabled
の仕様変更
エラー:snowflake_userのterraform plan
実行時に以下のエラーが起きました。
╷
│ Error: expected [{{} disabled}] to be one of ["true" "false"], got
│
│ with module.developer_sagara.snowflake_user.this,
│ on ../../modules/user/main.tf line 6, in resource "snowflake_user" "this":
│ 6: disabled = var.disabled
│
╵
原因は、disabled
がtrue
かfalse
どちらかの値しか受け付けなくなったことです。(詳細)
このため、disabled
のvariableの定義を以下の内容に変更しました。
variable "disabled" {
description = "If true, the target user will not be deleted but deactivated"
type = bool
default = false
}
account
が廃止され、account_name
とorganization_name
に移行
警告:providerの認証に使用するterraform plan
実行時に以下の警告が出ました。
╷
│ Warning: Argument is deprecated
│
│ with provider["registry.terraform.io/snowflakedb/snowflake"].terraform,
│ on versions.tf line 13, in provider "snowflake":
│ 13: account = var.environment == "prod" ? var.snowflake_prod_account : var.snowflake_dev_account
│
│ Use `account_name` and `organization_name` instead of `account`
╵
原因は、v0.98.0からaccount_name
とorganization_name
が追加されたためです。(詳細)
このため、以下の手順で修正を行いました。
dev
フォルダとprod
フォルダ内のvariables.tf
でaccount_name
とorganization_name
に対応したvariableを追加
# prodアカウント名は環境変数「TF_VAR_snowflake_prod_account_name」で定義する
variable "snowflake_prod_account_name" {
description = "Snowflakeのprodアカウント名 (例: xy123)"
type = string
}
# devアカウント名は環境変数「TF_VAR_snowflake_dev_account_name」で定義する
variable "snowflake_dev_account_name" {
description = "Snowflakeのdevアカウント名 (例: ab456)"
type = string
}
# prodアカウントの組織名は環境変数「TF_VAR_snowflake_prod_org_name」で定義する
variable "snowflake_prod_org_name" {
description = "Snowflakeのprod組織名 (例: abc)"
type = string
}
# devアカウントの組織名は環境変数「TF_VAR_snowflake_dev_org_name」で定義する
variable "snowflake_dev_org_name" {
description = "Snowflakeのdev組織名 (例: def)"
type = string
}
- 環境変数でアカウント名を管理しているため、
.profile
で環境変数を追加
export TF_VAR_snowflake_dev_account_name="AAA_DEV" # devアカウント名
export TF_VAR_snowflake_prod_account_name="AAA_PROD" # prodアカウント名
export TF_VAR_snowflake_dev_org_name="BBB" # dev組織名
export TF_VAR_snowflake_prod_org_name="CCC" # prod組織名
- GitHub Actionsのワークフローの定義上の環境変数名も追加・変更
env:
# Snowflake
TF_VAR_snowflake_dev_account_name: ${{ secrets.TF_VAR_SNOWFLAKE_DEV_ACCOUNT_NAME }}
TF_VAR_snowflake_prod_account_name: ${{ secrets.TF_VAR_SNOWFLAKE_PROD_ACCOUNT_NAME }}
TF_VAR_snowflake_dev_org_name: ${{ secrets.TF_VAR_SNOWFLAKE_DEV_ORG_NAME }}
TF_VAR_snowflake_prod_org_name: ${{ secrets.TF_VAR_SNOWFLAKE_PROD_ORG_NAME }}
- GitHub上でsecretsの値を追加した環境変数に合わせて、追加・変更
v0.98.0⇛v0.99.0へのアップグレード
Migration Guide
主なアップグレード時の修正内容
特に問題なく、versionを上げるだけでアップグレード出来ました。
v0.99.0⇛v1.0.0(v0.100.0と同時にリリース)へのアップグレード
Migration Guide
- v0.99.0⇛v0.100.0のMigration Guide
- v0.100.0⇛v1.0.0のMigration Guide
主なアップグレード時の修正内容
JWT
からSNOWFLAKE_JWT
に変更
authenticatorがterraform plan
実行時に以下のエラーが出ました。
╷
│ Error: invalid authenticator type: JWT
│
│ with provider["registry.terraform.io/snowflakedb/snowflake"].terraform,
│ on versions.tf line 16, in provider "snowflake":
│ 16: authenticator = "JWT"
│
╵
原因は、v0.100.0からproviderのauthenticator
でJWT
が指定不可となり、代わりにSNOWFLAKE_JWT
を指定するようになったためです。(詳細)
対策として、dev
フォルダとprod
フォルダ内のversions.tf
の中で、authenticator = "SNOWFLAKE_JWT"
に変更しました。
v1.0.0⇛v1.1.0へのアップグレード
Migration Guide
※v1.0.5⇛v1.10.0のMigration Guideへのリンクとなります
主なアップグレード時の修正内容
特に問題なく、versionを上げるだけでアップグレード出来ました。
v1.1.0⇛v1.2.0へのアップグレード
Migration Guide
主なアップグレード時の修正内容
特に問題なく、versionを上げるだけでアップグレード出来ました。
v1.2.0⇛v2.0.0へのアップグレード
Migration Guide
※v1.2.1⇛v2.0.0のMigration Guideへのリンクとなります
主なアップグレード時の修正内容
特に問題なく、versionを上げるだけでアップグレード出来ました。
最後に
terraform-provider-snowflakeをv0.88.0からv2.0.0にアップグレードしてみたので、その内容をまとめてみました。
私が対応したのはデータベース・スキーマ・ウェアハウス・ロール・ユーザーあたりのリソースしか定義していない簡易なリポジトリでしたが、それでも大変でしたね…(特にv0.95.0でバンドル2024_08以降だとエラーになるバグを踏んだのが辛かったです…)
今回Cursorを使って対応していたのですが、Cursorがなければ倍以上の時間がかかっていたと思います…
v2.0.0からはSnowflake公式でGAとなったので、Snowflakeへのサポートも起票可能となります。アップグレードの際に、この記事がどなたかの参考になると幸いです。