❄️

Workspaces上からSnowflake Terraform ProviderでCI/CDしてみよう

に公開

こんにちは。
株式会社アシストにてMDSエンジニア・Snowflakeエンジニアをしている山本です。
業務ではお客様のSnowflakeを中心としたデータ分析基盤の構築支援を行っています。

Workspaces上からSnowflake Terraform ProviderでCI/CDしてみよう

Snowflakeが激推し(後述)の統合開発環境(IDE)である「Workspaces」を活用して、Snowflake Terraform Providerのソースコードを編集し、CI/CDパイプラインを構築することを考えてみます。

記事対象者

Snowflakeのことは知っているけど、

  • CI/CDが何なのか良く知らない人
  • Snowflake Terraform Providerが何なのか良く知らない人
  • Snowflake Workspacesを使ったことがない人
  • SQLベースでのインフラストラクチャ管理に困っている人

必要な前提条件

  • GitHubアカウント
  • Snowflakeアカウント
  • AWSアカウント
  • Gitの基礎知識
  • GitHub Actionsの基礎知識(サンプルコードのみ後述)
  • AWSの基礎知識
  • Terraformの基礎知識(サンプルコードのみ後述)

Snowflake Terraform Providerの記法は、公式サイトを見ながら書いていけば初心者でも問題ないかと思います。

CI/CDとは

CI/CDとは

  • Continuous Integration(継続的インテグレーション)
  • Continuous Deployment(継続的デプロイメント)

を組み合わせた開発手法です。
https://about.gitlab.com/ja-jp/blog/getting-started-with-gitlab-understanding-ci-cd/

CI(継続的インテグレーション)

  • 意味:コードの変更を頻繁に統合し、自動テストを実行
  • メリット
    • バグを早期発見
    • チーム開発での競合を最小化
    • コード品質の維持

CD(継続的デプロイメント)

  • 意味:テストが通ったコードを自動的に本番環境に反映
  • メリット
    • 手動作業の削減
    • デプロイエラーの減少
    • 迅速な機能リリース

Terraformにおいてはこの流れがCI/CDと呼べるのではないでしょうか。

git push

terraform fmt

terraform init

terraform validate

terraform plan ←ここまでがCI(この後に人間がプルリクエストでレビューする)

terraform apply ←ここがCD

ここで使うGitHub Actionsとは、GitHubが提供するCI/CDプラットフォームです。
GitHub Actionsによってこの流れが自動化されるというのがCI/CDの醍醐味です。
https://github.co.jp/features/actions

CI/CDの具体的なメリット

開発者個人にとって

  • バグの早期発見:コードをgit pushした直後にテストが実行される
  • 手動作業の削減:デプロイ作業が自動化される
  • 安心感:テストが通ったコードのみが本番に反映される

プロジェクト/開発チームにとって

  • 品質の統一:全員のコードが同じ基準でテストされる
  • 開発速度の向上:手動確認作業が減り、開発に集中できる
  • 知識の共有:ワークフローが可視化され、チーム全体で理解しやすい

会社/組織にとって

  • コスト削減:手動作業の削減により人件費を節約
  • リスク軽減:自動テストにより本番障害を防止
  • スケーラビリティ:チームが大きくなっても品質を維持

Terraformとの親和性

TerraformCI/CDは以下の観点から非常に相性が良い組み合わせと言われています:

  1. コード化されたインフラ:Terraformはコードでインフラを管理
  2. 再現性:同じコードから同じ環境を何度でも作成可能
  3. バージョン管理:Gitでインフラの変更履歴を管理
  4. 自動化:CI/CDでインフラの変更を自動実行

Snowflake Terraform Providerとは

HashiCorp Terraform はオープンソースの Infrastructure as Code (IaC) ツールで、インフラリソースを動的に構築、変更、バージョン管理することができます。 Terraform言語 を使って、必要な構成を記述した構成ファイルを作成します。Terraformはあなたの構成と現在の状態を比較し、新しいリソースを作成したり、既存のリソースを更新・削除したりする計画を生成します。計画は有向無サイクルグラフ(DAG)として実行され、これによりTerraformはリソース間の依存関係を理解し処理することができます。
https://docs.snowflake.com/ja/user-guide/terraform

Terraformをよく知らない人に言うならば、SQL言語ベースでのSnowflakeインフラをTerraform言語ベースでより厳密に宣言的管理[1]しやすくなるというのが伝わりやすいでしょうか。

CREATE WAREHOUSE YAMAMOTO_TF_WH
  WITH
    WAREHOUSE_TYPE = 'STANDARD'
    WAREHOUSE_SIZE = 'XSMALL'
    MAX_CLUSTER_COUNT = 1
    MIN_CLUSTER_COUNT = 1
    AUTO_SUSPEND = 180
    AUTO_RESUME = TRUE
    ENABLE_QUERY_ACCELERATION = FALSE
    INITIALLY_SUSPENDED = TRUE;

このSQLが、

resource "snowflake_warehouse" "tf_warehouse" {
  name                      = "YAMAMOTO_TF_WH"
  warehouse_type            = "STANDARD"
  warehouse_size            = "XSMALL"
  max_cluster_count         = 1
  min_cluster_count         = 1
  auto_suspend              = 180
  auto_resume               = true
  enable_query_acceleration = false
  initially_suspended       = true
}

このTerraformになる。
詳しいSnowflake Terraform Providerの記法は公式サイトを見ながら書いていきましょう。

https://github.com/snowflakedb/terraform-provider-snowflake?tab=readme-ov-file#snowflake-terraform-provider
https://registry.terraform.io/providers/snowflakedb/snowflake/latest/docs

Snowflake Terraform Providerでできること:

  • データベース・スキーマの作成・管理
  • ウェアハウスの設定
  • ユーザー・ロールの管理
  • データベースオブジェクト(テーブル、ビューなど)の作成
  • データ共有の設定

その他、安定機能・プレビュー機能でSnowflakeのほとんどのリソースを扱えます。これからもさらに追加されていくでしょう。

従来のデータベースインフラ構築・管理は、SnowSQL/Snowflake CLIやSnowsight上でのSQL実行などを使って手動で行っていましたが、Snowflake Terraform Providerを使うことで:

  • インフラ構造のバージョン管理が可能
  • 環境間での一貫性を保てる
  • レビュープロセスを通じた安全性の向上
  • 自動化による運用効率の改善

が実現できます。

Snowflake Workspacesとは

Snowflake Workspacesは、Snowflake上でリポジトリ全体を編集・実行(※SQLのみ)できるIDEです。
https://docs.snowflake.com/en/user-guide/ui-snowsight/workspaces

Pythonなどの実行はまだWorksheetsやNotebooksでしか実行できないようです。

色々なタイミングでWorkspacesをデフォルトにしませんか!?とポップアップして激推ししてくるので、SnowflakeとしてもSnowflake開発のスタンダードにしたいという思惑が感じられます。(個人の感想)
Workspacesを開くと出てくるポップアップ

主な特徴

  1. ブラウザベースのIDE

    • 追加のソフトウェアインストール不要(外部IDEを組織で導入する必要がない)
    • Snowflakeのアカウントにログインできるところならどこでも開発できる
  2. Git統合

    • GitHub、GitLabとの連携が可能(一部GitHubのみの機能あり)
    • 基本的なGit処理をノーコマンドで実行可能
  3. 多言語対応

    • SQL、Python、JavaScript、Markdown等に対応(対応言語だとハイライト機能あり。.mdファイルにプレビュー機能もついている。実行ができるのは現状SQLのみ)
  4. Snowflakeのデータソースとの統合

    • データベースへの直接アクセス
    • SQLクエリの実行結果をIDE内で確認

わざわざ組織のメンバー全員に外部IDEの環境設定をしなくてもいいというところが開発者にとっていいところでしょうか。ローカルPCのマシンスペックにも依存しませんしね。
往々にして開発プロジェクトにアサインされた際の環境構築に1営業日かかることもあるので、Snowflakeユーザーを作成すればすぐに開発にジョインできるというのもメリットなのではないでしょうか。

今回構築するアーキテクチャ

Snowflake公式のSnowflake Terraform Providerは、このようなアーキテクチャを描いているようです。
https://quickstarts.snowflake.com/guide/terraforming_snowflake/#0

今回は以下のようなアーキテクチャでSnowflake Terraform Providerを試していきます。
今回構築するアーキテクチャ(自作図)

.tfstateの管理とトランザクション管理のやり方はこちらのZennBookを参考にさせていただきました。backendとしてはS3以外も選択できるようですが、Snowflakeとの親和性的にもS3が最適なのではないかと思ったり。
https://zenn.dev/mnagaa/books/3d668d2dfc657e

Snowflake Terraform Providerで扱えるresources, data sourcesはプレビューも含めると果てしない量なので今回は最小構成で取り扱います。

WorkspacesでのCI/CDの構築

1. GitHubリポジトリの準備

Terraformのソースコードを管理するためのGitHubリポジトリを作成して、チームメンバーのGitHubアカウントをCollaboratorに追加しておきましょう。

2. Snowflake WorkspacesにCloneする

プロジェクトタブ配下にWorkspacesタブが存在しています。クリックすると既存のリポジトリがない場合は新規Workspaceが作成されるかと思います

Workspace名の下矢印からgit cloneを行えますが、GitHubへのAPI統合を作成する必要があります

API統合作成の際には、この方法がチーム開発で一番いいのではないでしょうかと思います。
OAuth認証でメンバーがGitHubアカウントで認証してCloneしましょう。

CREATE OR REPLACE API INTEGRATION team_git_oauth_integration
  API_PROVIDER = git_https_api
  API_ALLOWED_PREFIXES = ('https://github.com/')
  API_USER_AUTHENTICATION = (TYPE = SNOWFLAKE_GITHUB_APP)
  ENABLED = TRUE;

PATでの認証もありますが複数人のチーム開発で考えると、GitHub側でのCollaborators管理とSnowflake側での許可Secret管理で二重の手間になるかなと思いました。

多重制御でよりセキュアになるとは思います。

CREATE OR REPLACE API INTEGRATION team_git_pat_integration
  API_PROVIDER = git_https_api
  API_ALLOWED_PREFIXES = ('https://github.com/')
  ALLOWED_AUTHENTICATION_SECRETS = (developer_a_git_secret, developer_b_git_secret)
  ENABLED = TRUE;

OAuth2で一度認証すれば簡単にGit連携ができます。

GitHubのリポジトリからWorkspaceが作成出来たらTerraformのコードを書いていきましょう。

3. Terraformの基本構成

今回、構築するインフラのディレクトリ構成は下記のようなものにしました。
ロール設計やステージ設計まで入れると長くなりそうなので割愛で、今回はすべてSYSADMINでやります。

公開しているモジュールが複数ありますので、ロール設計・ステージ設計をされる方はご利用ください。
https://registry.terraform.io/providers/snowflakedb/snowflake/latest

zenn_article_terraform/
├── environments/
│   ├── dev/
│   │   ├── main.tf
│   │   ├── providers.tf
│   │   ├── variables.tf
│   │   ├── warehouses.tf
│   │   └── terraform.tfvars
│   └── prod/
│       ├── main.tf
│       ├── providers.tf
│       ├── variables.tf
│       └── terraform.tfvars
├── modules/
│   └── horizon_catalog
│       ├── yamamoto_terraform_db
│       │   ├── database.tf
│       │   ├── schemas.tf
│       │   ├── tables.tf
│       │   ├── versions.tf
│       │   └── outputs.tf
│       └── users_roles
│           ├── roles.tf
│           ├── users.tf
│           ├── variables.tf
│           ├── versions.tf
│           └── outputs.tf
└── .github/
    └── workflows/
        ├── terraform.yml
        └── unlock_state.yml (デッドロックが発生した時用)

https://github.com/yamamoto10152/zenn_article_terraform

variablesを設定しているのにデフォルト値も入力値も存在しない場合、デッドロックが発生してしまうようなのでロック解除のworkflowも入れています。

4. GitHub Actionsワークフローの設定

.github/workflows/terraform.ymlに以下のようなワークフローを作成しました。今回はネットワークポリシーを適用したPAT認証を用いています。

対応認証方法

Snowflake Providerの認証方法としては以下のものが対応しているようです。

  • Password
  • PAT (Personal Access Token)
  • OAuth Access Token
  • OAuth Refresh Token
  • Browser Auth
  • Private Key
  • Config File
  • Oauth with Client Credentials
  • Oauth with Authorization Code

https://github.com/yamamoto10152/zenn_article_terraform/blob/eef4fa0378f63626ecdc338a535d9112ddc3edeb/.github/workflows/terraform.yml

ASSUME_ROLEの使い方はこちらを参考にしました。
https://zenn.dev/shuk/articles/36c0fddf204552#1.githubでorganizationを設定する

GitHub Organization配下のリポジトリしかできないわけではなく、信頼エンティティに適当に作成した組織アカウントを並記しているだけで個人リポジトリでも使えました。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::xxxxxxx:oidc-provider/token.actions.githubusercontent.com"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {
                    "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
                },
                "StringLike": {
                    "token.actions.githubusercontent.com:sub": [
                        "repo:yamamoto10152/zenn_article_terraform:*",
                        "repo:<組織アカウント>/*:*"
                    ]
                }
            }
        }
    ]
}

5. GitHub Secretsの設定

GitHubリポジトリの「Settings」→「Secrets and variables」→「Actions」で以下のSecretsを設定します:

  • SNOWFLAKE_ORGANIZATION_NAME : Snowflake組織識別子
  • SNOWFLAKE_ACCOUNT_NAME : Snowflakeアカウント識別子
  • SNOWFLAKE_USER: Snowflakeユーザー名
  • SNOWFLAKE_PASSWORD: Snowflakeパスワード(今回はPATです)
  • ASSUME_ROLE_ARN: 信頼関係にGitHubのOICDプロバイダーを指定したロールのARN

6. Terraformファイルの編集

実際にSnowflake Terraform Providerを書いていきます。

上記の構成で完成したうえで、4番目のスキーマを追加しています。

7. Git操作

Workspace上で以下のGit操作が可能です:

  • ブランチの作成・切り替え
  • (一括コミット&)プッシュ
  • フェッチ
  • プル

変更が行われると、Changeタブで差分確認なども行えます。

個人的には、(一括コミット&)プッシュの挙動が解せません....
なぜそのような挙動に設計したのか....今後のアップデートに期待します....

Pushを選択するとCommitメッセージと共に実行してくれます

WorkspacesからのPushによってActionsが実行されています

Pullリクエストを出したらPlanが行われることになっているので、Plan結果を確認します。

変更履歴をレビューしてmainにマージするとApplyが実行されます。

8. インフラの変更を確認

第四スキーマは無かったのですがActionsが実行されて、一覧更新すると第四スキーマが現れました。
実行前
実行後

以上の流れでWorkspaces上で構築をしながら、GitHubでレビュープロセスを経て、Snowflakeインフラが管理・構築されていきます。

まとめ

”最初にWorkspacesにGitリポジトリをつなぐためのGit IntegrationはSQLで作らないといけない”
ということを除けばSnowflake WorkspacesでSQLなしに開発ができるというのが現状ですね。
Snowflake Terraform Providerを実行するサービスユーザーに強い権限を与えて、新しいオブジェクトを作る際にはWorkspacesで開発して管理・運用するというようにすれば、知らない間に色々なオブジェクトが増えて依存関係も分からなくなるといったことは避けられるでしょうか。

Snowflake管理者にGit管理の業務が増えるという点はありますが、Snowflake上に無駄なリソースが増えて組織全体のコストが増大していくよりはマシでしょう。

総評として、Snowflake WorkspaceとGitHub Actions(とAWS)を組み合わせることで、以下のような開発フローが実現できます:

  1. Snowflake Workspace上でのコード編集
  2. Git操作によるバージョン管理
  3. GitHub ActionsによるCI/CD
  4. Snowflakeリソースの自動プロビジョニング

この組み合わせにより、従来の手動SQLでのリソース管理から脱却し、ローカルIDEでの開発からも脱却し、効率的(?)で安全なインフラ管理が可能になります。


脚注
  1. 宣言的管理とは「最終的な状態を宣言し、システムが自動的にその状態を実現する」管理手法です。どのようなインフラの状態になっているのかを明確に宣言することで変更点を管理できます。 ↩︎

Discussion