こちらのページでは role によるアクセス制御を記載しました。本ページではネットワーク関連の設定について記載します。
/24
等で指定されており、その一部を block したい場合は blocked list を /32
等で作成します。Network policy の作成
CREATE NETWORK POLICY mypolicy ALLOWED_IP_LIST = ('123.123.123.123');
DESC NETWORK POLICY mypolicy;
User level での policy 設定
ALTER USER myuser SET NETWORK_POLICY = mypolicy;
設定されている policy の確認
SHOW PARAMETERS LIKE 'network_policy' IN ACCOUNT xxx12345;
SHOW PARAMETERS LIKE 'network_policy' IN USER myuser;
参考資料:
Bulk Loading from a Local File System
LIST @~
としてアクセスします。LIST @%mytable
としてアクセスします。Named Internal Stage の作成例
USE DATABASE mydb;
USE SCHEMA public;
CREATE OR REPLACE STAGE mystage
FILE_FORMAT = (TYPE=CSV FIELD_DELIMITER=',' SKIP_HEADER=1);
参考資料: Bulk Loading from a Local File System
補足: セキュリティについて考慮が不要な場合は、上図のように、Stage object を用いずに COPY コマンドに直接 AWS 認証情報を渡すことも可能です。参考資料: COPY INTO table
S3 バケットポリシーを設定している場合、Snowflake AWS VPC ID からのアクセスを許可する必要があります。
USE ROLE accountadmin;
SELECT system$get_snowflake_platform_info();
{"snowflake-vpc-id":["vpc-xxxxxxxxxxxxxxxxx"]}
補足: Snowflake アカウントの Cloud Provider として AWS を利用している場合、Snowflake VPC には Gateway 型の S3 VPC Endpoint が存在しています。そのため、顧客管理の External Stage が AWS S3 でありかつ同一リージョンに存在している場合に限り、External Stage と Snowflake の通信がインターネットを経由することはありません。
補足2: Snowflake アカウントの Cloud Provider が AWS 以外であったり、AWS の他のリージョンである場合には、Gateway 型の VPC Endpoint 経由のアクセスとならず、したがって、S3 バケットポリシーを設定している場合に VPC ID によってアクセスを許可することができません。
S3 バケットポリシーの設定例
{
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::my-test-20210923",
"arn:aws:s3:::my-test-20210923/*"
],
"Condition": {
"StringNotEquals": {
"aws:sourceVpc": [
"vpc-xxxxxxxxxxxxxxxxx"
],
"aws:PrincipalArn": "arn:aws:iam::123412341234:user/myadmin"
}
}
}
]
}
参考資料:
Option 1: Configuring a Snowflake Storage Integration to Access Amazon S3
Snowflake アカウントに紐付けられた IAM user が Assume して利用する IAM role を、顧客管理 AWS アカウントに作成します。
補足: Snowflake アカウントが存在する Cloud Provider によらず、AWS IAM user が Snowflake アカウントに紐付けられます。
補足2: Read 権限のみで良い場合は、s3:PutObject
, s3:DeleteObject
, s3:DeleteObjectVersion
は不要です。
IAM に付与する Policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:GetObjectVersion",
"s3:PutObject",
"s3:DeleteObject",
"s3:DeleteObjectVersion"
],
"Resource": "arn:aws:s3:::my-test-20210923/snowflake/*"
},
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation"
],
"Resource": "arn:aws:s3:::my-test-20210923",
"Condition": {
"StringLike": {
"s3:prefix": [
"snowflake/*"
]
}
}
}
]
}
Trust relationship の Principal AWS ARN と sts:ExternalId
に対しては、一時的に適当な値を指定します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111222333444:user/xxxxxxxxxxxxxxx"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "0000"
}
}
}
]
}
作成しておいた IAM role の ARN を STORAGE_AWS_ROLE_ARN
に指定します。
CREATE STORAGE INTEGRATION mys3int
TYPE = EXTERNAL_STAGE
STORAGE_PROVIDER = S3
ENABLED = true
STORAGE_AWS_ROLE_ARN = 'arn:aws:iam::123412341234:role/my-role-20210923'
STORAGE_ALLOWED_LOCATIONS = ('s3://my-test-20210923/snowflake/');
STORAGE_AWS_IAM_USER_ARN
および STORAGE_AWS_EXTERNAL_ID
を確認して IAM role の Trust relationship に入力します。
DESC INTEGRATION mys3int;
CREATE DATABASE mydb;
USE SCHEMA mydb.public;
CREATE STAGE mys3stage
STORAGE_INTEGRATION = mys3int
URL = 's3://my-test-20210923/snowflake/'
FILE_FORMAT = (TYPE=CSV FIELD_DELIMITER=',' SKIP_HEADER=1);
動作確認
LIST @mys3stage;
CREATE OR REPLACE TABLE mytbl (
c1 STRING,
c2 DATE
);
USE WAREHOUSE mywh;
COPY INTO mytbl
FROM @mys3stage
PATTERN ='.*\.csv';
STORAGE INTEGRATION object を DESC して得られる STORAGE_AWS_IAM_USER_ARN
および STORAGE_AWS_EXTERNAL_ID
を、顧客管理 AWS で許可する方法の他に、以下のような認証方法が存在します。
SNOWFLAKE_IAM_USER
および AWS_EXTERNAL_ID
を、顧客管理 AWS で許可する方法です。
AWS_KEY_ID
と AWS_SECRET
を指定する方法です。
参考資料: Bulk Loading from Google Cloud Storage
Configuring an Integration for Google Cloud Storage
CREATE STORAGE INTEGRATION my_gcs_int
TYPE = EXTERNAL_STAGE
STORAGE_PROVIDER = GCS
ENABLED = true
STORAGE_ALLOWED_LOCATIONS = ('gcs://mybucket-20210925');
Snowflake アカウント内で利用される GCP Service Account を確認します。
補足: Snowflake アカウントの Cloud Provider は GCP である必要はありません。
DESC STORAGE INTEGRATION my_gcs_int;
STORAGE_GCP_SERVICE_ACCOUNT
xxxxxxxxxx@va2-10fd.iam.gserviceaccount.com
GCS における権限を Service Account に対して付与します。
Data Load に必要な permission
storage.buckets.get
storage.objects.get
storage.objects.list
Data Unload の場合は、加えて以下の permission も必要です。
storage.objects.create
storage.objects.delete
カスタムロールを作成する、または標準の IAM Role を付与します: Understanding roles
Data Load の場合
Storage Legacy Bucket Reader
Storage Legacy Object Reader
Data Unload の場合
Storage Legacy Bucket Writer
Storage Legacy Object Reader
CREATE DATABASE mydb;
CREATE STAGE my_gcs_stage
URL = 'gcs://mybucket-20210925/snowflake'
STORAGE_INTEGRATION = my_gcs_int
FILE_FORMAT = (TYPE=CSV FIELD_DELIMITER=',' SKIP_HEADER=1);
動作確認
LIST @my_gcs_stage;
CREATE OR REPLACE TABLE mytbl (
c1 STRING,
c2 DATE
);
CREATE OR REPLACE WAREHOUSE mywh WITH
WAREHOUSE_SIZE = XSMALL
AUTO_SUSPEND = 60
AUTO_RESUME = true
INITIALLY_SUSPENDED = true;
COPY INTO mytbl
FROM @my_gcs_stage
PATTERN ='.*\.csv';
Data Load の場合と同様に Stage を作成します。
PUT
ではなく GET
コマンドを利用します。Internal User Stage へのファイルアップロード
cat /tmp/data.csv
aaa,8/25/2017
bbb,12/10/2017
ccc,10/18/2017
ddd,8/13/2017
eee,11/27/2017
PUT file:///tmp/data.csv @~;
Internal Stage 内のファイルへの SELECT
LIST @~;
+-----------------------------------------------------+------+----------------------------------+-------------------------------+
| name | size | md5 | last_modified |
|-----------------------------------------------------+------+----------------------------------+-------------------------------|
| data.csv.gz | 96 | 2df4a4a4750befe338230eeeb9046e6a | Sat, 25 Sep 2021 07:47:54 GMT |
| worksheet_data/e0f64b2d-1c2f-4e96-9e25-136daefa1d15 | 384 | b242dab6c7af72ec9cd16420554b9e13 | Sat, 25 Sep 2021 07:44:41 GMT |
| worksheet_data/metadata | 416 | 17c37abdd89b4d183ceb3f7d4566a44b | Sat, 25 Sep 2021 07:44:42 GMT |
+-----------------------------------------------------+------+----------------------------------+-------------------------------+
CREATE OR REPLACE WAREHOUSE mywh WITH
WAREHOUSE_SIZE = XSMALL
AUTO_SUSPEND = 60
AUTO_RESUME = true
INITIALLY_SUSPENDED = true;
SELECT t.$1, t.$2 FROM @~/data.csv AS t;
+-----+------------+
| $1 | $2 |
|-----+------------|
| aaa | 8/25/2017 |
| bbb | 12/10/2017 |
| ccc | 10/18/2017 |
| ddd | 8/13/2017 |
| eee | 11/27/2017 |
+-----+------------+
参考資料:
Snowpipe は data load を micro-batch 処理で実現するための仕組みです。二種類の方法がサポートされています。
AWS S3 や GCP Cloud Storage に備わっている Messaging 機能を利用する方法です。Snowflake アカウントと顧客管理 External Storage が同じ Cloud Provider に存在している場合、およびその他の一部の組み合わせについてサポートされています。
補足: AWS を Cloud Provider として利用している Snowflake アカウントの場合に限り、すべての External Stage に対応しています。
Automating Continuous Data Loading Using Cloud Messaging
External Stage または Internal Stage にファイルをアップロードした後に、アップロードしたアプリケーションが REST API を実行することで、Snowpipe による COPY (Data Load) 処理をトリガします。
参考資料: Calling Snowpipe REST Endpoints to Load Data
顧客管理 AWS S3 を External Stage として利用している場合を考えます。S3 にファイルがアップロードされた際に S3 から Snowflake アカウント内の SQS に対して Notification が通知される設定を行います。
注意: Snowflake アカウントの Cloud Provider は AWS であり、かつ顧客管理 AWS S3 と同一リージョンである必要があります。
関連資料:
Snowpipe は COPY コマンドを micro-batch 処理で実行するための仕組みです。まずは COPY コマンド実行に必要となる Storage Integration および Stage を作成します。設定方法は前述の通りです。
s3:PutObject
, s3:DeleteObject
, s3:DeleteObjectVersion
は不要です。CREATE PIPE mydb.public.mypipe
AUTO_INGEST = true
AS COPY INTO mydb.public.mytbl
FROM @mydb.public.mys3stage
PATTERN ='.*\.csv';
参考資料: CREATE PIPE
Snowpipe に紐付けられた SQS の ARN を確認します。
SHOW pipes;
Object Create Events を通知するように設定します。
SQS ARN を設定します。
S3 バケットの snowflake フォルダに CSV ファイルをアップロードすると Snowpipe が自動的に table に data load します。以下のコマンドでログ等を確認できます。
Snowpipe のステータス
SELECT system$pipe_status('mydb.public.mypipe');
Snowpipe 自体のエラーログ
SELECT * FROM TABLE(VALIDATE_PIPE_LOAD(
PIPE_NAME => 'mydb.public.mypipe',
START_TIME => DATEADD(HOUR, -2, CURRENT_TIMESTAMP())));
Snowpipe が実行した COPY コマンドのログ
SELECT * FROM TABLE (INFORMATION_SCHEMA.COPY_HISTORY(
table_name => 'mydb.public.mytbl',
START_TIME => DATEADD(HOUR, -2, CURRENT_TIMESTAMP())))
ORDER BY LAST_LOAD_TIME DESC;
snowpipe 一覧
SHOW pipes;
SHOW pipes IN DATABASE mydb;
SHOW pipes IN SCHEMA mydb.public;
SQS 内のメッセージ処理を一時停止
ALTER PIPE mydb.public.mypipe SET PIPE_EXECUTION_PAUSED = true;
7日以内に Stage されたファイルを Snowpipe SQS にコピー: ALTER PIPE
ALTER PIPE mydb.public.mypipe REFRESH;
顧客管理 AWS S3 から Snowflake アカウント内 SQS に対する通知は VPC の外の通信となります: Network Traffic
S3 の Event Notification を同一の Path に複数作成することはできません。Snowflake SQS 連携以外の用途でも Notification が必要となる場合は、S3 から直接 SQS に通知するのではなく、SNS を介するように設定します。
関連資料: Amazon Comprehend を GCP VPC 内から実行する設定の例 (Public Internet 接続なし)
SNS Access Policy
{
"Version": "2008-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": [
"SNS:GetTopicAttributes",
"SNS:SetTopicAttributes",
"SNS:AddPermission",
"SNS:RemovePermission",
"SNS:DeleteTopic",
"SNS:Subscribe",
"SNS:ListSubscriptionsByTopic",
"SNS:Publish",
"SNS:Receive"
],
"Resource": "arn:aws:sns:us-east-1:123412341234:my-s3-topic",
"Condition": {
"StringEquals": {
"AWS:SourceOwner": "123412341234"
}
}
}
]
}
S3 からのアクセスを許可。Statement に追加します。
{
"Effect": "Allow",
"Principal": {
"Service": "s3.amazonaws.com"
},
"Action": [
"sns:Publish"
],
"Resource": "arn:aws:sns:us-east-1:123412341234:my-s3-topic",
"Condition": {
"ArnLike": { "aws:SourceArn": "arn:aws:s3:::my-test-20210923" },
"StringEquals": { "aws:SourceAccount": "123412341234" }
}
}
Snowflake SQS からのアクセスを許可。以下のコマンドで確認できる結果を Statement に追加します。
SELECT system$get_aws_sns_iam_policy('arn:aws:sns:us-east-1:123412341234:my-s3-topic');
関連資料: SYSTEM$GET_AWS_SNS_IAM_POLICY
SNS に対して Notification 設定を追加します。
AWS_SNS_TOPIC
を指定することに注意します。
CREATE PIPE mydb.public.mypipe
AUTO_INGEST = true
AWS_SNS_TOPIC = 'arn:aws:sns:us-east-1:123412341234:my-s3-topic'
AS COPY INTO mydb.public.mytbl
FROM @mydb.public.mys3stage
PATTERN ='.*\.csv';
関連資料: CREATE PIPE
Snowflake アカウントの Cloud Provider が AWS の場合に限り、顧客管理 AWS が Snowflake アカウントの AWS と同一リージョンであれば、以下の三つの通信をすべてインターネットを経由せずに実現できます。
com.amazonaws.vpce.<region_id>.vpce-svc-xxxxxxxxxxxxxxxxx
という形式の VPC Endpoint Service が提供されます。privatelink-account-url
privatelink-ocsp-url
参考資料:
GCP 向けにも同様の機能が提供され始めました。2021/8/5 に GA となった Private Service Connect を利用しています。
関連資料:
以下のような Snowflake クライアントが存在します。
Snowflake を利用するために必要となるアクセス先の一覧は、以下の関数で取得できます。AWS が Cloud Provider である Snowflake アカウントを利用した出力例を記載しています。Firewall を利用している場合は、設定でアクセスを許可する必要があります。
参考資料:
SELECT system$whitelist();
利用関数: SYSTEM$WHITELIST
[
{
"type": "SNOWFLAKE_DEPLOYMENT", ← Web UI を含めた Snowflake サービス。
"host": "xxx12345.us-east-1.snowflakecomputing.com",
"port": 443
},
{
"type": "SNOWFLAKE_DEPLOYMENT_REGIONLESS", ← Organization 利用時の場合はこちらも可。
"host": "orgname-accountname.snowflakecomputing.com",
"port": 443
},
{
"type": "STAGE", ← Internal Stage。
"host": "sfc-xxx-xxx-32-customer-stage.s3.us-east-1.amazonaws.com",
"port": 443
},
{
"type": "STAGE", ← Internal Stage。
"host": "sfc-xxx-xxx-32-customer-stage.s3-us-east-1.amazonaws.com",
"port": 443
},
{
"type": "STAGE", ← Internal Stage。
"host": "sfc-xxx-xxx-32-customer-stage.s3.amazonaws.com",
"port": 443
},
{
"type": "SNOWSQL_REPO", ← SnowSQL が自動アップグレードするために必要。
"host": "sfc-repo.snowflakecomputing.com",
"port": 443
},
{
"type": "OUT_OF_BAND_TELEMETRY", ← 利用状況の情報を Snowflake 社に通知。
"host": "client-telemetry.snowflakecomputing.com",
"port": 443
},
{
"type": "OCSP_CACHE", ← Snowflake が提供する OCSP 情報。
"host": "ocsp.snowflakecomputing.com",
"port": 80
},
{
"type": "DUO_SECURITY", ← 二段階認証時。
"host": "api-xxxxxxxx.duosecurity.com",
"port": 443
},
{
"type": "OCSP_RESPONDER", ← OCSP 情報。
"host": "ocsp.digicert.com",
"port": 80
},
{
"type": "OCSP_RESPONDER", ← OCSP 情報。
"host": "o.ss2.us",
"port": 80
},
{
"type": "OCSP_RESPONDER", ← OCSP 情報。
"host": "ocsp.rootg2.amazontrust.com",
"port": 80
},
{
"type": "OCSP_RESPONDER", ← OCSP 情報。
"host": "ocsp.sca1b.amazontrust.com",
"port": 80
},
{
"type": "OCSP_RESPONDER", ← OCSP 情報。
"host": "ocsp.rootca1.amazontrust.com",
"port": 80
}
]
SELECT system$whitelist_privatelink();
利用関数: SYSTEM$WHITELIST_PRIVATELINK
[
{
"type": "SNOWFLAKE_DEPLOYMENT", ← Web UI を含めた Snowflake サービス。
"host": "xxx12345.us-east-1.privatelink.snowflakecomputing.com",
"port": 443
},
{
"type": "STAGE", ← Internal Stage。
"host": "sfc-xxx-xxx-32-customer-stage.s3.us-east-1.amazonaws.com",
"port": 443
},
{
"type": "STAGE", ← Internal Stage。
"host": "sfc-xxx-xxx-32-customer-stage.s3-us-east-1.amazonaws.com",
"port": 443
},
{
"type": "STAGE", ← Internal Stage。
"host": "sfc-xxx-xxx-32-customer-stage.s3.amazonaws.com",
"port": 443
},
{
"type": "SNOWSQL_REPO", ← SnowSQL が自動アップグレードするために必要。
"host": "sfc-repo.snowflakecomputing.com",
"port": 443
},
{
"type": "OUT_OF_BAND_TELEMETRY", ← 利用状況の情報を Snowflake 社に通知。
"host": "client-telemetry.snowflakecomputing.com",
"port": 443
},
{
"type": "OCSP_CACHE", ← Snowflake が提供する OCSP 情報。
"host": "ocsp.xxx12345.us-east-1.privatelink.snowflakecomputing.com",
"port": 80
},
{
"type": "DUO_SECURITY", ← 二段階認証。
"host": "api-xxxxxxxx.duosecurity.com",
"port": 443
}
]
上記の情報の一部は、以下の関数で取得できる情報と一致します。
USE ROLE accountadmin;
ALTER ACCOUNT SET enable_internal_stages_privatelink = true;
SELECT system$get_privatelink_config();
利用関数: SYSTEM$GET_PRIVATELINK_CONFIG
{
"privatelink-account-name": "xxx12345.us-east-1.privatelink",
"privatelink-internal-stage": "sfc-xxx-xxx-32-customer-stage.s3.us-east-1.amazonaws.com",
"privatelink-vpce-id": "com.amazonaws.vpce.us-east-1.vpce-svc-xxxxxxxxxxxxxxxxx",
"privatelink-account-url": "xxx12345.us-east-1.privatelink.snowflakecomputing.com",
"privatelink_ocsp-url": "ocsp.xxx12345.us-east-1.privatelink.snowflakecomputing.com",
"privatelink-connection-urls": "[]"
}