PulumiでSnowflakeのロールを作成してみた

2022.06.15

こんにちは!DA(データアナリティクス)事業本部 サービスソリューション部の大高です。

Infrastructure as Code のツール「Pulumi」はSnowflakeにも対応しており、下記の通りSnowflake用のパッケージが提供されています。

先日、こちらのパッケージを利用して下記のエントリの通りSnowflakeの「仮想ウェアハウス」作成を試してみたのですが、今回は「ロール」を作成してみたいと思います。

前提

Snowflakeのアカウントは既にセットアップ済みで利用できるものとします。

また、Pulumiについては下記のようにHomebrew経由でインストールされていることを前提としています。

% brew install pulumi
% pulumi version
v3.34.1

加えて、PulumiのプロジェクトとSnowflake接続用の設定は下記のエントリの通り設定済みであることを前提としています。

ロールを作成するコードを記述する

では、ドキュメントを参考にしながらコードを記述していきましょう。

resources/role.ts

import * as snowflake from "@pulumi/snowflake";
import { RoleArgs } from "@pulumi/snowflake";

export class Role {
  name: string;

  constructor(name: string) {
    this.name = name;
  }

  public create(args: RoleArgs): snowflake.Role {
    const role = new snowflake.Role(this.name, {
      name: this.name,
      ...args,
    });

    return role;
  }
}

まずは、index.tsとは別のファイルにクラスとしてロール作成用コードを分離して記述していみました。コード自体はシンプルで、ロール名はコンストラクタで与えられたものを指定し、(引数に与えられれば)ロール用引数をマージして設定しているだけです。

また、今回の検証スコープから外れますが仮想ウェアハウスの作成についても以下のコードを書いてみました。

resources/warehouse.ts

import * as snowflake from "@pulumi/snowflake";
import { WarehouseArgs } from "@pulumi/snowflake";

export class Warehouse {
  name: string;

  constructor(name: string) {
    this.name = name;
  }

  public create(args: WarehouseArgs): snowflake.Warehouse {
    const warehouse = new snowflake.Warehouse(this.name, {
      name: this.name,
      autoSuspend: 60,
      ...args,
    });

    return warehouse;
  }
}

こちらもほぼロールと同じです。自動サスペンド(autoSuspend)の時間だけ、デフォルトで60秒にしています。

あとはこれらをindex.tsから呼び出します。

index.ts

import { Role } from "./resources/role";
import { Warehouse } from "./resources/warehouse";

// Role
const role = new Role("role-ootaka-pulumi");
role.create({});

// Warehouse
const warehouse = new Warehouse("vwh-ootaka-pulumi");
warehouse.create({ warehouseSize: "xsmall" });

// Export Resource Info
export const roleInfo = role;
export const warehouseInfo = warehouse;

こちらは作成したクラスを単純に呼んでいるだけですね。

デプロイしてみる、その前に。。。

では、早速デプロイしてみます。

と言いたいところですが、今回は実行時に利用する「ロール」にちょっと注意が必要です。

今回実行するコードでは、ROLEWAREHOUSEを作成しています。つまり、SQLで言えばCREATE ROLECREATE WAREHOUSEをすることになります。

これには、それぞれドキュメントに記載のとおり以下の権限が必要です。

必要な権限 権限を持つロール
CREATE ROLE USERADMIN または それ以上のロール
CREATE WAREHOUSE SYSADMIN または それ以上のロール

また、今回はこの程度ですが更に色々なリソースを作成したい場合には、更に上位のロールが必要となるケースもあります。

ここはとても悩ましいのですが、今回の検証ではACCOUNTADMINをPulumiでの構築用ロールとして設定したいと思います。(本来であれば、必要最小限なロールや権限を組み合わせた専用のロールを適宜作成するべきかなと思います)

ということで、下記のコマンドを実行しました。

% pulumi config set snowflake:role ACCOUNTADMIN

デプロイしてみる

では、デプロイしてみます。

デプロイにはpulumi upコマンドを実行します。

% pulumi up     
Previewing update (dev)

View Live: https://app.pulumi.com/ootaka-daisuke/pulumi-snowflake/dev/previews/c6a0d16c-a8b5-446b-b1fa-cca7c35b2409

     Type                          Name                  Plan       
 +   pulumi:pulumi:Stack           pulumi-snowflake-dev  create     
 +   ├─ snowflake:index:Role       role-ootaka-pulumi    create     
 +   └─ snowflake:index:Warehouse  vwh-ootaka-pulumi     create     
 
Resources:
    + 3 to create

Do you want to perform this update?  [Use arrows to move, enter to select, type to filter]
  yes
> no
  details

作成リソースのプレビュー後にyesを選択し、成功すると以下のように表示されます。

Do you want to perform this update? yes
Updating (dev)

View Live: https://app.pulumi.com/ootaka-daisuke/pulumi-snowflake/dev/updates/13

     Type                          Name                  Status      
 +   pulumi:pulumi:Stack           pulumi-snowflake-dev  created     
 +   ├─ snowflake:index:Role       role-ootaka-pulumi    created     
 +   └─ snowflake:index:Warehouse  vwh-ootaka-pulumi     created     
 
Outputs:
    roleInfo     : {
        id     : "role-ootaka-pulumi"
        name   : "role-ootaka-pulumi"
        urn    : "urn:pulumi:dev::pulumi-snowflake::snowflake:index/role:Role::role-ootaka-pulumi"
    }
    warehouseInfo: {
        autoResume                     : true
        autoSuspend                    : 60
        id                             : "vwh-ootaka-pulumi"
        maxClusterCount                : 1
        maxConcurrencyLevel            : 8
        minClusterCount                : 1
        name                           : "vwh-ootaka-pulumi"
        resourceMonitor                : "null"
        scalingPolicy                  : "STANDARD"
        statementQueuedTimeoutInSeconds: 0
        statementTimeoutInSeconds      : 172800
        urn                            : "urn:pulumi:dev::pulumi-snowflake::snowflake:index/warehouse:Warehouse::vwh-ootaka-pulumi"
        warehouseSize                  : "X-Small"
    }

Resources:
    + 3 created

Duration: 4s

実際にsnowsqlを利用してSQLでロールと仮想ウェアハウスの情報を確認してみます。

USE ROLE ACCOUNTADMIN;
SHOW ROLES LIKE 'role-ootaka-pulumi';
+-------------------------------+--------------------+------------+------------+--------------+-------------------+------------------+---------------+--------------+---------+
| created_on                    | name               | is_default | is_current | is_inherited | assigned_to_users | granted_to_roles | granted_roles | owner        | comment |
|-------------------------------+--------------------+------------+------------+--------------+-------------------+------------------+---------------+--------------+---------|
| 2022-06-14 23:13:23.265 -0700 | role-ootaka-pulumi | N          | N          | N            |                 0 |                0 |             0 | ACCOUNTADMIN |         |
+-------------------------------+--------------------+------------+------------+--------------+-------------------+------------------+---------------+--------------+---------+
1 Row(s) produced. Time Elapsed: 0.196s
SHOW WAREHOUSES LIKE 'vwh-ootaka-pulumi';
+-------------------+-----------+----------+---------+-------------------+-------------------+------------------+---------+--------+------------+------------+--------------+-------------+-----------+--------------+-----------+-------+-------------------------------+-------------------------------+-------------------------------+--------------+---------+------------------+---------+----------+--------+-----------+----------+----------------+
| name              | state     | type     | size    | min_cluster_count | max_cluster_count | started_clusters | running | queued | is_default | is_current | auto_suspend | auto_resume | available | provisioning | quiescing | other | created_on                    | resumed_on                    | updated_on                    | owner        | comment | resource_monitor | actives | pendings | failed | suspended | uuid     | scaling_policy |
|-------------------+-----------+----------+---------+-------------------+-------------------+------------------+---------+--------+------------+------------+--------------+-------------+-----------+--------------+-----------+-------+-------------------------------+-------------------------------+-------------------------------+--------------+---------+------------------+---------+----------+--------+-----------+----------+----------------|
| vwh-ootaka-pulumi | SUSPENDED | STANDARD | X-Small |                 1 |                 1 |                0 |       0 |      0 | N          | N          |           60 | true        |           |              |           |       | 2022-06-14 23:13:23.278 -0700 | 2022-06-14 23:13:23.488 -0700 | 2022-06-14 23:13:23.489 -0700 | ACCOUNTADMIN |         | null             |       0 |        0 |      0 |         1 | 11796785 | STANDARD       |
+-------------------+-----------+----------+---------+-------------------+-------------------+------------------+---------+--------+------------+------------+--------------+-------------+-----------+--------------+-----------+-------+-------------------------------+-------------------------------+-------------------------------+--------------+---------+------------------+---------+----------+--------+-----------+----------+----------------+
1 Row(s) produced. Time Elapsed: 0.510s

想定どおり作成できていますね!

最後に、pulumi destroyコマンドで後片付けをしておしまいです。

まとめ

以上、PulumiでSnowflakeのロールを作成してみました。

今回は実際には仮想ウェアハウスも同時に作成したので、作成時に利用するロールについては悩みましたが、ロールの作成自体は簡単でしたね。

どなたかのお役に立てば幸いです。それでは!