AWS 계정이 있고 S3 버킷을 사용하여 데이터 파일을 저장 및 관리하는 경우
Snowflake로 대량 로드하기 위해 기존 버킷과 폴더 경로를 사용할 수 있습니다.
S3 버킷에서 테이블로 대량 로드하는 COPY 명령에 대한 사용 방법을 설명합니다.
일반적으로 Snowflake에서 데이터를 가져오거나 클라우드 서비스(예: S3)와 통합하기 위해 인증 정보를 사용해야 할 때, 해당 클라우드 공급자의
비밀 키
또는액세스 토큰
과 같은 자격 증명을 설정해야 한다.
그러나
Integration
을 사용하면
명시적인 자격 증명을 전달하지 않고도 클라우드 공급자와의 통합을 수행할 수 있다.
Integration
개체는Snowflake에서 관리되는 개체
로,
클라우드 공급자와의 연결 및 자격 증명 정보를 중앙에서 관리한다.
Integration
을 사용하면 개발자는 자격 증명 정보를 코드에 하드코딩하지 않고도 클라우드 서비스와의 통합을 수행할 수 있다.
보안 및 개발자의 편의성 측면에서 이점을 제공한다.
CREATE OR REPLACE STAGE csv_s3_stage
STORAGE_INTEGRATION = test_s3_snow <-- Integration 정의
URL = 's3://snow-test-bucket/test/'
FILE_FORMAT = my_csv_format;
Snowflake
는 계정에 대해 생성된 S3 IAM 사용자와 저장소 통합을 자동으로 연결합니다. Snowflake
는 Snowflake
계정의 모든 S3 저장소 통합에서 참조하는 단일 IAM 사용자를 생성합니다.
조직의 AWS 관리자가 IAM 사용자에게 스테이지 정의에서 참조하는 버킷에 액세스할 수 있는 권한을 부여합니다.
많은 외부 스테이지 오브젝트가 다른 버킷과 경로를 참조하고 인증에서 동일한 저장소 통합을 사용할 수 있습니다.
CREATE OR REPLACE STAGE csv_s3_stage
STORAGE_INTEGRATION = test_s3_snow
URL = 's3://snow-test-bucket/test/' <-- 참조된 S3 Bucket 경로
FILE_FORMAT = my_csv_format;
Snowflake의 AWS Region과 같은 Region에 있는 S3 bucket이어야 한다.
작성자에 경우, 같은 서울 Region 확인
Snowflake ID 및 IAM 엔티티에 클라우드 저장소에 대한 인증 책임을 위임하도록
Snowflake Integration을 구성하는 방법 설명
Snowflake가 폴더(및 하위 폴더)의 파일에 액세스하기 위해 필요한 S3 버킷 및 폴더 권한은 다음과 같습니다.
s3:GetBucketLocation
s3:GetObject
s3:GetObjectVersion
s3:ListBucket
-- 하위 두 항목은 추가적인 사항입니다.
s3:PutObject
- 파일을 Bucket에 Unload 시,
s3:DeleteObject
- Stage에서 파일 제거 시,
: 위의 권한들을 가진 IAM Policy를 다음과 같이 작성한다.
구조
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:GetObjectVersion", "s3:DeleteObject", "s3:DeleteObjectVersion" ], "Resource": "arn:aws:s3:::<bucket>/<prefix>/*" }, { "Effect": "Allow", "Action": [ "s3:ListBucket", "s3:GetBucketLocation" ], "Resource": "arn:aws:s3:::<bucket>", "Condition": { "StringLike": { "s3:prefix": [ "<prefix>/*" ] } } } ] }
<bucket>
: 권한을 가질 S3 bucket
<prefix>
: 권한을 가질 S3 오브젝트의 경로
*
: 와일드 카드로 모든 것을 의미한다.
(예:<prefix>/*
는<prefix>
아래 모든 오브젝트)
예시
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:GetObjectVersion", "s3:DeleteObject", "s3:DeleteObjectVersion" ], "Resource": "arn:aws:s3:::snow-test-bucket/test/*" }, { "Effect": "Allow", "Action": [ "s3:ListBucket", "s3:GetBucketLocation" ], "Resource": "arn:aws:s3:::snow-test-bucket", "Condition": { "StringLike": { "s3:prefix": [ "test/*" ] } } } ] }
<bucket>
: snow-test-bucket
<prefix>
: test
1. AWS Console 로그인
2. 대시보드에서 Identity & Access Management (IAM)를 선택
3. 정책 (Policy) 선택
4. 정책 (Policy) 생성 선택
5. JSON 선택 후, 작성했던 Policy 그대로 작성
6. 정책 이름 작성하고 생성
1. AWS Console 로그인
2. 대시보드에서 Identity & Access Management (IAM)를 선택
3. 역할 (Role) 선택
4. 역할 (Role) 생성
외부 ID
는 나중에Integration
이 생성되고 나면 변경할 것이기 때문에
임시로 0000 을 입력해놓고 다음 단계로 넘어간다.
- 전에 생성한 Policy를 적용하여 Role 생성을 완료한다.
이것으로 S3 버킷에 대한 IAM Policy를 만들고 그 Policy를 Role에 부여했다.
CREATE STORAGE INTEGRATION <integration_name> TYPE = EXTERNAL_STAGE STORAGE_PROVIDER = 'S3' ENABLED = TRUE STORAGE_AWS_ROLE_ARN = '<iam_role>' STORAGE_ALLOWED_LOCATIONS = ('s3://<bucket>/<path>/', 's3://<bucket>/<path>/') [ STORAGE_BLOCKED_LOCATIONS = ('s3://<bucket>/<path>/', 's3://<bucket>/<path>/') ]
integration_name
- 새 통합의 이름입니다.
iam_role
- AWS에서 IAM 역할 만들기 에서 생성한 역할의 Amazon 리소스 이름(ARN)입니다.
<bucket>
- 데이터 파일을 저장하는 S3 버킷의 이름입니다(예: mybucket).
<path>
- 버킷의 오브젝트를 세부적으로 제어하기 위해 사용할 수 있는 선택적 경로입니다.
예시
CREATE OR REPLACE STORAGE INTEGRATION test_s3_snow TYPE = EXTERNAL_STAGE STORAGE_PROVIDER = 'S3' ENABLED = TRUE STORAGE_AWS_ROLE_ARN = 'arn:aws:iam::{---}/test-snow-role' STORAGE_ALLOWED_LOCATIONS = ('*'); --[ STORAGE_BLOCKED_LOCATIONS = ('s3://<bucket>/<path>/', 's3://<bucket>/<path>/') ]
DESC INTEGRATION <integration_name>;
여기서 다음 값을 기록한다.
STORAGE_AWS_IAM_USER_ARN
STORAGE_AWS_EXTERNAL_ID
1. AWS Console 로그인
2. 대시보드에서 Identity & Access Management (IAM)를 선택
3. 역할 (Role) 선택
4. 생성했던 역할 (Role) 선택 후, 신뢰 관계 (Trust relationship) 탭 선택
5. 신뢰 관계 (Trust relationship) 수정 후 업데이트
구조
{ "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "AWS": "<snowflake_user_arn>" }, "Action": "sts:AssumeRole", "Condition": { "StringEquals": { "sts:ExternalId": "<snowflake_external_id>" } } } ] }
snowflake_user_arn
- 사용자가 기록한 STORAGE_AWS_IAM_USER_ARN 값입니다.
snowflake_external_id
- 사용자가 기록한 STORAGE_AWS_EXTERNAL_ID 값입니다.
-- External Stage 만들기 준비
-- CREATE OR REPLACE ROLE s3role;
-- GRANT CREATE STAGE ON SCHEMA public TO ROLE s3role;
-- GRANT USAGE ON INTEGRATION test_s3_snow TO ROLE s3role;
CREATE OR REPLACE DATABASE s3db;
USE DATABASE s3db;
USE SCHEMA s3db.public;
-- File_Format 생성
CREATE OR REPLACE FILE FORMAT my_csv_format
TYPE = CSV
FIELD_DELIMITER = ','
SKIP_HEADER = 1
NULL_IF = ('NULL', 'null')
EMPTY_FIELD_AS_NULL = true;
-- 외부 Stage 만들기
CREATE OR REPLACE STAGE csv_s3_stage
STORAGE_INTEGRATION = test_s3_snow
URL = 's3://snow-test-bucket/test/';
FILE_FORMAT = my_csv_format;
S3에 데이터 적재
-- 데이터 로드하기
ALTER WAREHOUSE COMPUTE_WH RESUME;
CREATE OR REPLACE TABLE s3table1 (
id VARCHAR(100),
first_name VARCHAR(100),
last_name VARCHAR(100)
);
COPY INTO s3table1
FROM @csv_s3_stage
PATTERN='.*.csv'
FILE_FORMAT = my_csv_format;
SELECT * FROM s3table1