Snowflake

This guide explains how to create a read-only service account (metadata access only) for Revefi on Snowflake.

Step 1: Create role, user, warehouse and grant account permissions

As a super user, execute the following SQL commands to create a read-only role, a user assigned to that role, and a warehouse for that role.

Please note:
Make sure to generate a secure password for the field called <strong_password_for_revefi_read_only_access> and store it securely — you'll save it into Revefi later.
Revefi will use an XS warehouse by default. This setting can be modified later if necessary.
We recommend using Snowflake's worksheet interface to run the snippet. Please copy the code and make any necessary modifications before running it.

-- Use a role with sufficient privileges to grant the below permissions
USE ROLE ACCOUNTADMIN;

-- Configuration
set revefi_username='REVEFI_USER';
set revefi_password='<strong_password_for_revefi_read_only_access>';
set revefi_warehouse_size='XSMALL';
set revefi_warehouse_name='REVEFI_WH';
set revefi_role_name='REVEFI_ROLE';

-- Create warehouse for Revefi's monitoring workload
CREATE WAREHOUSE IF NOT EXISTS identifier($revefi_warehouse_name) WAREHOUSE_SIZE=$revefi_warehouse_size INITIALLY_SUSPENDED=TRUE AUTO_SUSPEND = 60 AUTO_RESUME = TRUE MAX_CONCURRENCY_LEVEL = 32 STATEMENT_TIMEOUT_IN_SECONDS = 1200 STATEMENT_QUEUED_TIMEOUT_IN_SECONDS = 1200;
 
-- Create the role Revefi will use
CREATE ROLE IF NOT EXISTS identifier($revefi_role_name);
 
-- Create Revefi's user and grant access to role
CREATE USER IF NOT EXISTS identifier($revefi_username) PASSWORD=$revefi_password  DEFAULT_ROLE=$revefi_role_name; 
GRANT ROLE identifier($revefi_role_name) TO USER identifier($revefi_username);
 
-- Grant permissions to use the new warehouse
-- OPERATE allows Revefi to start and stop the warehouse.
GRANT OPERATE, USAGE, MONITOR ON WAREHOUSE identifier($revefi_warehouse_name) TO ROLE identifier($revefi_role_name);
 
-- Grant privileges to allow access to query history and other account level metadata
GRANT IMPORTED PRIVILEGES ON DATABASE "SNOWFLAKE" TO ROLE identifier($revefi_role_name);

Step 2: Provide metadata access to each database you want to monitor

Please note:
Replace <db_to_monitor> with the actual name of the database you want to monitor

-- Use a role with sufficient privileges to grant the below permissions
USE ROLE ACCOUNTADMIN;

-- Configuration
set revefi_role_name='REVEFI_ROLE';
-- NOTE: If your database name has special characters, please double quote the name:
-- https://docs.snowflake.com/en/sql-reference/identifiers-syntax#double-quoted-identifiers
-- E.g. set database_name = '"prod-orders"';
set database_name = '<db_to_monitor>';

-- Grant permission to run the USE command on database and schemas
GRANT USAGE on database identifier($database_name) to role identifier($revefi_role_name);
GRANT USAGE ON ALL SCHEMAS IN DATABASE identifier($database_name) TO ROLE identifier($revefi_role_name);
GRANT USAGE ON FUTURE SCHEMAS IN DATABASE identifier($database_name) TO ROLE identifier($revefi_role_name);

-- Grant permission to view tables and their schemas
GRANT REFERENCES ON ALL TABLES IN DATABASE identifier($database_name) TO ROLE identifier($revefi_role_name);
GRANT REFERENCES ON FUTURE TABLES IN DATABASE identifier($database_name) TO ROLE identifier($revefi_role_name);

-- Grant permission to view views and their schemas
GRANT REFERENCES ON ALL VIEWS IN DATABASE identifier($database_name) TO ROLE identifier($revefi_role_name);
GRANT REFERENCES ON FUTURE VIEWS IN DATABASE identifier($database_name) TO ROLE identifier($revefi_role_name);

USE DATABASE identifier($database_name);
-- By default the below procedure is created in the PUBLIC schema of the specified database.
-- If a PUBLIC schema does not exist, please un-comment the below line and specify any schema name of your choice.
-- USE SCHEMA <schema_name>;

-- Snowflake allows granting privileges either for a database or a schema. However, schema privileges take precedence.
-- This has an unfortunate side-effect for future grants, explained here: https://community.snowflake.com/s/article/DB-Level-Future-Grants-Overridden-by-Schema-Level-Future-Grants
-- Any schema level FUTURE grants to one role, will cause Snowflake to dis-regard all db level FUTURE grants to other roles.
-- This below stored procedure checks whether any FUTURE grants exists for a schema. If they do, it grants Revefi FUTURE grants for that schema.
-- If no FUTURE grants exist for any schema, the below stored procedure is a no-op.
CREATE OR REPLACE PROCEDURE GRANT_SCHEMA_REFERENCES_TO_REVEFI()
  RETURNS VARCHAR
  LANGUAGE javascript
  EXECUTE AS CALLER
  AS
  $$
  // Check for existing future grants to each schema. If they exist, grant future privileges to Revefi for that schema. 
  var schemas_to_grant = snowflake.createStatement({ sqlText:`select * from information_schema.SCHEMATA where SCHEMA_NAME <> 'INFORMATION_SCHEMA'`}).execute();
  var discovered_schemas = "";
  var granted_schemas = "";
  while(schemas_to_grant.next()) {
    table_schema = schemas_to_grant.getColumnValue("SCHEMA_NAME");
    discovered_schemas += table_schema + ","
    var show_future_grants_result = snowflake.createStatement({sqlText: `SHOW FUTURE GRANTS IN SCHEMA "${table_schema}"`}).execute();
    if (show_future_grants_result.getRowCount() > 0) {
        snowflake.createStatement({ sqlText:`GRANT REFERENCES ON ALL TABLES IN SCHEMA "${table_schema}" TO ROLE identifier($revefi_role_name)`}).execute();
        snowflake.createStatement({ sqlText:`GRANT REFERENCES ON FUTURE TABLES IN SCHEMA "${table_schema}" TO ROLE identifier($revefi_role_name)`}).execute();
        snowflake.createStatement({ sqlText:`GRANT REFERENCES ON ALL VIEWS IN SCHEMA "${table_schema}" TO ROLE identifier($revefi_role_name)`}).execute();
        snowflake.createStatement({ sqlText:`GRANT REFERENCES ON FUTURE VIEWS IN SCHEMA "${table_schema}" TO ROLE identifier($revefi_role_name)`}).execute();


        granted_schemas += table_schema + ","
    }
  }
      
  return `Discovered schemas: [${discovered_schemas}]. Granted references for schemas: [${granted_schemas}] (if blank, no schema grants were needed)`;
  $$;
 
CALL GRANT_SCHEMA_REFERENCES_TO_REVEFI();

Step 3: Provide permissions to analyze query performance and view Warehouse configurations

  • Revefi requires the MONITOR privilege on Snowflake warehouses to analyze queries for performance bottlenecks and provide optimization recommendations.
  • The USAGE privilege is needed to view the Snowflake warehouse parameters. Revefi will only use a single warehouse (from Step 1) for all queries.

Please run the below script to grant this privilege to Revefi on a per Snowflake warehouse basis:

-- Use any existing database name that your current role has access to, this is only used to temporarily create the stored procedure below
SET db_for_procedure='<any_database>';

-- Manually grant permissions to one warehouse at a time using:
-- GRANT MONITOR ON WAREHOUSE <warehouse_name> TO ROLE identifier($revefi_role_name)
-- GRANT USAGE ON WAREHOUSE <warehouse_name> TO ROLE identifier($revefi_role_name)
--
-- To grant the permission for all your warehouses together:
USE DATABASE identifier($db_for_procedure);
CREATE OR REPLACE PROCEDURE GRANT_WAREHOUSE_PRIVILEGES_TO_REVEFI()
    RETURNS VARCHAR
    LANGUAGE javascript
    EXECUTE AS CALLER
AS
$$
var warehouses_to_grant = snowflake.createStatement({ sqlText:`SHOW WAREHOUSES`}).execute();
var granted_warehouses = "";
while(warehouses_to_grant.next()) {
  warehouse_name = warehouses_to_grant.getColumnValue("name");
  snowflake.createStatement({ sqlText:`GRANT USAGE ON WAREHOUSE "${warehouse_name}" TO ROLE identifier($revefi_role_name)`}).execute();
  snowflake.createStatement({ sqlText:`GRANT MONITOR ON WAREHOUSE "${warehouse_name}" TO ROLE identifier($revefi_role_name)`}).execute();
  granted_warehouses += warehouse_name + ", "
}

return `Granted monitor and usage on warehouses: [${granted_warehouses}]`;
$$;

-- Invoke the procedure and clean up
CALL GRANT_WAREHOUSE_PRIVILEGES_TO_REVEFI();
DROP PROCEDURE GRANT_WAREHOUSE_PRIVILEGES_TO_REVEFI();

Step 4: Provide permissions to MONITOR USAGE ON ACCOUNT

🚧

This is an optional step. Run this only if Revefi will monitor all tables across all your databases

This permission gives Revefi the ability to see the configuration settings of future warehouses as well.

-- Allow Revefi to view all database names and the configuration settings of all 
-- current and future warehouses
GRANT MONITOR USAGE ON ACCOUNT TO ROLE identifier($revefi_role_name);

Step 5: Warehouse Management Privileges (Optional)

🚧

This is an optional step. This is needed by Revefi to manage and execute warehouse recommendations.

Revefi uses Snowflake task to execute warehouse recommendations.

Run the below script to create a dedicated DB for revefi to store tasks and procedures needed for warehouse recommendations:

SET revefi_db='REVEFI_DB';

-- Create a dedicated database for REVEFI to use to create tasks and procedures needed for automangement
CREATE DATABASE identifier($revefi_db);

-- Grant usage on all schemas and db
GRANT USAGE ON ALL SCHEMAS IN DATABASE identifier($revefi_db) TO ROLE identifier($revefi_role_name);
GRANT USAGE on database identifier($revefi_db) to role identifier($revefi_role_name);

USE DATABASE identifier($revefi_db);

-- Grant permissions to create procedure and tasks in revefi_db
GRANT CREATE PROCEDURE ON SCHEMA PUBLIC TO ROLE identifier($revefi_role_name);
GRANT CREATE TASK ON SCHEMA PUBLIC TO ROLE identifier($revefi_role_name);
GRANT EXECUTE TASK ON ACCOUNT TO ROLE identifier($revefi_role_name);

Run the below script to provide permissions to revefi to execute warehouse recommendations:

-- To give permissions to selected warehouses one at a time, run the following command with warehouse name replaced
-- GRANT MODIFY ON WAREHOUSE <warehouse_name> TO ROLE identifier($revefi_role_name);

-- To grant the permission for all your warehouses together:
CREATE OR REPLACE PROCEDURE GRANT_WAREHOUSE_AUTO_MANAGEMENT_PRIVILEGES_TO_REVEFI()
    RETURNS VARCHAR
    LANGUAGE javascript
    EXECUTE AS CALLER
AS
$$
var warehouses_to_grant = snowflake.createStatement({ sqlText:`SHOW WAREHOUSES`}).execute();
var granted_warehouses = "";
while(warehouses_to_grant.next()) {
  warehouse_name = warehouses_to_grant.getColumnValue("name");
  snowflake.createStatement({ sqlText:`GRANT MODIFY ON WAREHOUSE "${warehouse_name}" TO ROLE identifier($revefi_role_name)`}).execute();
  granted_warehouses += warehouse_name + ", "
}

return `Granted operate on warehouses: [${granted_warehouses}]`;
$$;

-- Invoke the procedure and clean up
CALL GRANT_WAREHOUSE_AUTO_MANAGEMENT_PRIVILEGES_TO_REVEFI();
DROP PROCEDURE GRANT_WAREHOUSE_AUTO_MANAGEMENT_PRIVILEGES_TO_REVEFI();

Additional security considerations

  1. Allowlist Revefi IP addresses (if applicable)
    Add Revefi IP addresses (44.225.56.55, 44.227.173.42, 52.10.141.35) to your Snowflake account if Snowflake is configured to only allow connections from an "allowed list" of IP addresses.

  2. Snowflake supports using key pair authentication for enhanced authentication security as an alternative to basic authentication (i.e. username and password). If you enable that for the user you use for Revefi monitoring, then follow the "Key pair authentication" path in the Connect to Snowflake page in Revefi. If you use encrypted private key, then make sure to fill in the Private key passphrase, otherwise leave that field blank for unencrypted private key.

FAQ

  1. The CREATE OR REPLACE PROCEDURE GRANT_SCHEMA_REFERENCES_TO_REVEFI() statement creates the procedure under the chosen database's PUBLIC schema. If the database does not have a PUBLIC schema, you may see an error. In this case, simply select another schema in the database (either with the USE SCHEMA command or from the Snowflake Worksheet UI) and re-run the script.
  2. The CALL GRANT_SCHEMA_REFERENCES_TO_REVEFI(); statement requires a warehouse to be selected in the Snowflake Worksheet UI. This can be any warehouse that you have access to - not restricted to the warehouse created earlier.
  3. In Step 2, for database names with special characters, please double quote the name. For e.g. set database_name = '"prod-orders"'.

What’s Next

Once you have run this Snowflake script, go to the Connections page in Revefi on the left nav, and click Connect on the Snowflake box to enter the credentials for the Revefi user created above! Once that's done, optionally set up to receive your alerts via Slack (default is your email).