Snowflake에서 Foundry Iceberg 카탈로그 사용하기
Snowflake는 Iceberg REST catalog integration으로 Foundry가 관리하는 Iceberg 테이블에 연결할 수 있습니다. 반대 방향인 Foundry에서 Snowflake로의 연결은 Snowflake 소스를 사용합니다.
Snowflake는 현재 CSE가 적용된 이 경로의 테이블을 읽을 수 없습니다. 네트워크와 인증이 준비되어도 형식 및 암호화 호환 조건은 별도로 충족해야 합니다. 저장 및 암호화 조건을 먼저 확인합니다.
네트워크와 권한
Snowflake에서 Foundry 도메인과 기반 저장소로 나갈 수 있어야 하고, Foundry 및 저장소에서도 Snowflake의 실제 발신 IP 또는 VPC endpoint를 허용해야 합니다. 외부 접근의 두 엔드포인트 조건을 적용합니다.
Catalog integration 생성에는 계정의 CREATE INTEGRATION 권한이 필요합니다. ACCOUNTADMIN이 이 권한을 가진 기본 경로이며 필요한 권한을 부여받은 역할을 사용할 수도 있습니다. 통합 확인 및 조회에는 integration의 USAGE가 필요합니다. 로컬 Iceberg 테이블을 만드는 역할에는 대상 스키마의 CREATE ICEBERG TABLE과 부모 데이터베이스 및 스키마의 적절한 접근 권한도 필요합니다.
Foundry에는 client credentials grant를 사용하는 앱을 준비하고 서비스 사용자에 실제 폴더와 테이블 권한을 부여합니다. OAuth scope는 그 권한을 대신하지 않습니다. 보호된 main 테이블에 쓰는 경우에는 Foundry 브랜치 보호 권한도 확인합니다.
SQL에 넣을 실제 값
아래 SQL은 환경별 값을 넣는 구성 템플릿입니다. 꺾쇠 항목을 그대로 실행하지 않고 다음 실제 값으로 치환합니다. 식별자와 문자열은 Snowflake의 인용 규칙에 맞춰 작성합니다.
| 입력 | 의미 |
|---|---|
INTEGRATION_NAME | 새 Snowflake catalog integration 이름 |
FOUNDRY_ORIGIN | 실제 Foundry HTTPS 기본 URL. /iceberg는 포함하지 않습니다. |
FOUNDRY_NAMESPACE | 점으로 구분한 실제 이름 공간. 예를 들어 Namespace.Project.tables는 해당 Compass 폴더를 나타냅니다. |
CLIENT_ID, CLIENT_SECRET | 실제 Foundry 앱의 client credentials |
DATABASE, SCHEMA, LOCAL_TABLE | 테이블 링크를 만들 Snowflake 위치와 이름 |
TABLE_RID | 연결할 실제 Foundry Iceberg 테이블 RID |
LINKED_DATABASE | 선택적으로 생성할 catalog-linked database 이름 |
Client Secret은 실제 인증에 필요한 비밀 입력입니다. 해당 값이 들어간 SQL 파일을 코드 저장소나 공유 노트북에 보관하지 않습니다.
Catalog integration 생성
CREATE CATALOG INTEGRATION <INTEGRATION_NAME>
CATALOG_SOURCE = ICEBERG_REST
TABLE_FORMAT = ICEBERG
ENABLED = TRUE
CATALOG_NAMESPACE = '<FOUNDRY_NAMESPACE>'
REST_CONFIG = (
CATALOG_NAME = 'foundry'
CATALOG_URI = '<FOUNDRY_ORIGIN>/iceberg'
CATALOG_API_TYPE = 'public'
ACCESS_DELEGATION_MODE = VENDED_CREDENTIALS
)
REST_AUTHENTICATION = (
TYPE = OAUTH
OAUTH_TOKEN_URI = '<FOUNDRY_ORIGIN>/iceberg/v1/oauth/tokens'
OAUTH_CLIENT_ID = '<CLIENT_ID>'
OAUTH_CLIENT_SECRET = '<CLIENT_SECRET>'
OAUTH_ALLOWED_SCOPES = ('api:iceberg-read', 'api:iceberg-write')
);
읽기만 사용할 경우 OAUTH_ALLOWED_SCOPES에는 api:iceberg-read만 지정합니다. 쓰기를 사용할 때는 api:iceberg-write와 Foundry 서비스 사용자의 실제 쓰기 권한이 모두 필요합니다.
VENDED_CREDENTIALS는 Foundry 카탈로그가 발급한 범위 제한 단기 저장소 인증 정보를 사용하라는 설정입니다. 이 경로의 테이블에는 EXTERNAL_VOLUME을 지정하지 않습니다. 기본 external volume이 계정, 데이터베이스나 스키마에 있어도 vended-credentials 구성이 우선합니다. 원래 버킷의 인증 정보를 클라이언트에 별도로 배포하지 않습니다.
통합 확인과 목록 조회
SELECT SYSTEM$VERIFY_CATALOG_INTEGRATION('<INTEGRATION_NAME>');
이 함수는 실제 카탈로그 서버에 접근하여 인증과 접근 구성을 확인합니다. 통합 이름은 대소문자를 구분하므로 생성한 실제 이름과 맞춥니다. 반환 JSON의 success가 true인지 확인합니다. SQL 호출 자체가 완료된 것만으로 검증 성공을 판단하지 않습니다. 실패 시 errorCode와 errorMessage가 원인 정보를 제공합니다.
이름 공간과 테이블 목록도 확인합니다.
SELECT SYSTEM$LIST_NAMESPACES_FROM_CATALOG(
'<INTEGRATION_NAME>',
'<FOUNDRY_NAMESPACE>',
1
);
SELECT SYSTEM$LIST_ICEBERG_TABLES_FROM_CATALOG(
'<INTEGRATION_NAME>',
'<FOUNDRY_NAMESPACE>',
1
);
세 번째 인수 1은 이름 공간의 한 수준을 탐색하는 값이며 결과를 한 행으로 제한하는 값이 아닙니다. 인증에 실패하면 카탈로그 인증 진단에서 사용자 토큰, 앱 scope와 서비스 사용자 권한을 나누어 확인합니다.
Foundry 테이블 등록과 읽기
다음은 실제 Foundry 테이블 RID로 링크하는 구성입니다.
CREATE OR REPLACE ICEBERG TABLE <DATABASE>.<SCHEMA>.<LOCAL_TABLE>
CATALOG = '<INTEGRATION_NAME>'
CATALOG_TABLE_NAME = '<TABLE_RID>'
CATALOG_NAMESPACE = 'foundry'
AUTO_REFRESH = TRUE;
SELECT * FROM <DATABASE>.<SCHEMA>.<LOCAL_TABLE>;
RID 대신 실제 Foundry 테이블 이름을 CATALOG_TABLE_NAME에 지정하고 그 테이블의 이름 공간을 CATALOG_NAMESPACE에 지정하는 방식도 사용할 수 있습니다. 이름과 이름 공간을 한 쌍으로 맞춥니다.
등록과 SELECT는 Foundry 테이블을 덮어쓰거나 삭제하는 동작이 아닙니다. 다만 CREATE OR REPLACE는 같은 이름의 Snowflake 로컬 객체를 교체하므로 그 대상을 확인해야 합니다.
선택 사항: Foundry 테이블에 쓰기
지원되는 외부 REST 카탈로그 테이블에는 Snowflake에서 쓸 수도 있습니다. Foundry의 쓰기 scope와 테이블 쓰기 권한 및 필요한 브랜치 보호 예외를 확인합니다. 다음은 세 열에 행 하나를 넣는 SQL 형식입니다. 실제 열 이름과 SQL 값 리터럴을 대상 스키마에 맞춰 지정합니다.
INSERT INTO <DATABASE>.<SCHEMA>.<LOCAL_TABLE>
(<COLUMN_1>, <COLUMN_2>, <COLUMN_3>)
VALUES
(<VALUE_1>, <VALUE_2>, <VALUE_3>);
이 단계는 실제 Foundry 데이터를 변경합니다. 읽기 연결을 확인하는 단계와 구분하여 실행합니다.
선택 사항: Catalog-linked database
통합을 데이터베이스에 연결할 수도 있습니다.
CREATE DATABASE <LINKED_DATABASE>
LINKED_CATALOG = (
CATALOG = '<INTEGRATION_NAME>'
);
SELECT SYSTEM$CATALOG_LINK_STATUS('<LINKED_DATABASE>');
이 명령은 실제 Snowflake 데이터베이스를 생성합니다. 생성할 이름과 권한을 확인하고 서버가 반환한 링크 상태를 검토합니다.