Azure 환경에서 Snowflake를 Private Link로 구성하고, Azure Blob Storage와 안전하게 데이터를 연동하는 방법에 대해서 알아보겠습니다.
[아키텍처 개요]
Cloud Provider : Microsoft Azure (Korea Central)
Data Platform : Snowflake (Enterprise Edition)
Network : Public Access 차단, Azure Private Link를 통한 폐쇄망 구성
Storage : Azure Blob Storage (데이터 적재용)
Part 1. Snowflake - Azure Private Link 구성
Snowflake와 Azure 간의 Private Link 구성은 Handshake -> Endpoint -> DNS 3단계로 이루어집니다.
Step 1. Snowflake 정보 추출 (Snowflake)
먼저 Snowflake가 Azure Private Link 서비스에 연결될 수 있도록, Snowflake의 privatelink-pls-id를 Azure에게 전달해야 합니다.
SELECT SYSTEM$GET_PRIVATELINK_CONFIG();
전달 정보: privatelink-pls-id (예: sf-pvlinksvc-azkoreacentral...)
Step 2. Azure Private Endpoint 생성 (Azure)
ID를 사용하여 Azure Portal에서 Private Endpoint를 생성합니다. 그리고 생성된 Endpoint의 리소스 ID와 승인용 토큰을 추출하여 전달합니다.
필요 정보: Private Endpoint Resource ID, Azure Access Token (유효시간 주의)
Step 3. 연결 승인 (Snowflake)
전달받은 토큰을 사용하여 Snowflake에서 연결을 최종 승인합니다.
SELECT SYSTEM$AUTHORIZE_PRIVATELINK(
'<Private Endpoint Resource ID>',
'<Azure Access Token>'
);
Step 4. DNS 라우팅 설정 (Azure)
Snowflake는 여러 개의 URL(로그인, 앱, OCSP 등)을 사용하므로, Azure Private DNS Zone에 각각 레코드를 등록해야 합니다.
[필수 등록 DNS Zone]
privatelink.snowflakecomputing.com (기본 접속)
privatelink.snowflake.app (Snowsight 앱 등)
registry.privatelink.snowflakecomputing.com (Snowpark Container Service 등)
설정 후 nslookup 수행 시 Public IP가 아닌 내부 Private IP가 반환되어야 성공입니다.
Part 2. Azure Blob Storage 연동
Step 1. Azure 스토리지 정보 준비
가장 먼저 연동할 Azure Storage Account의 기본 정보를 확보해야 합니다.
Azure Tenant ID: (예: a0863...)
Storage Account Name: (예: mydata_storage)
Container Name: (예: snowflake-data)
Directory Path: (필요시, 예: /raw/)
Step 2. Snowflake Integration 생성 및 정보 추출
Snowflake에서 Azure와의 연결 고리 역할을 하는 STORAGE INTEGRATION 객체를 생성합니다.
-- 1. Integration 생성
CREATE OR REPLACE STORAGE INTEGRATION azure_blob_int
TYPE = EXTERNAL_STAGE
STORAGE_PROVIDER = 'AZURE'
ENABLED = TRUE
AZURE_TENANT_ID = '[Azure_Tenant_ID]'
STORAGE_ALLOWED_LOCATIONS = ('azure://[Storage_Account].blob.core.windows.net/[Container]/');
-- 2. 생성된 정보 확인 (Azure 전달용)
DESC STORAGE INTEGRATION azure_blob_int;
확인해야 할 값 (Azure 전달용):
AZURE_CONSENT_URL: 관리자 동의를 위한 링크
AZURE_MULTI_TENANT_APP_NAME: Snowflake 앱 식별자 (예: ..._1767166889530)
Step 3. Azure AD 승인 및 IAM 권한 부여
Azure 에게 전달받은 URL 승인과 권한 부여를 요청합니다.
1. 관리자 동의 (Consent)
전달받은 AZURE_CONSENT_URL에 접속하여 **[수락(Accept)]**을 클릭해야 합니다.
이 과정이 선행되어야 Azure AD에 Snowflake 서비스 주체가 생성됩니다.
2. IAM 역할 할당 (Role Assignment)
리소스: 해당 Storage Account
역할: Storage Blob Data Contributor
멤버: Snowflake 앱 이름 검색 후 추가
Step 4. 네트워크 보안 설정 (Private Link 환경 필수)
Private Link를 사용하는 폐쇄망 환경이라면, 스토리지의 방화벽이 닫혀 있을 확률이 높습니다. 이 경우 Snowflake가 접근할 수 있도록 길을 열어줘야 합니다.
1. Snowflake VNet Subnet ID 확인 Snowflake 워크시트에서 아래 쿼리를 실행하여 VNet 정보를 확인합니다.
SELECT SYSTEM$GET_SNOWFLAKE_PLATFORM_INFO();
결과 JSON에서 snowflake-vnet-subnet-id 리스트를 확보합니다.
2. Azure Storage 방화벽 허용
위치: Storage Account > Networking > Firewalls and virtual networks
설정: 'Selected networks' 선택 후, 위에서 확인한 Snowflake Subnet ID를 등록합니다.
추가 체크: "Allow trusted Microsoft services..."(신뢰할 수 있는 서비스 허용) 체크박스도 활성화합니다.
Step 5. Stage 생성 및 최종 연결
데이터를 바라보는 Stage를 생성합니다.
-- External Stage 생성
CREATE OR REPLACE STAGE azure_blob_stage
STORAGE_INTEGRATION = azure_blob_int
URL = 'azure://[Storage_Account].blob.core.windows.net/[Container]/'
FILE_FORMAT = (TYPE = CSV);
마지막 관문: Private Endpoint 경로 설정
만약 연결 테스트(LIST 명령어) 중 아래와 같은 에러가 발생한다면 설정을 변경해야 합니다.
Error: Private endpoint corresponding to service name ... does not exist.
원인 : Snowflake는 Private Link 환경일 경우, 스토리지 접근 시에도 자동으로 Private Endpoint 경로를 찾으려 시도합니다. (TRUE가 기본값)
해결: Step 4에서 Service Endpoint(방화벽 허용) 방식으로 길을 열었으므로, Private Endpoint를 강제하지 않도록 설정을 꺼야 합니다.
-- Private Endpoint 강제 사용 옵션 해제
ALTER STORAGE INTEGRATION azure_blob_int
SET USE_PRIVATELINK_ENDPOINT = FALSE;
LIST @azure_blob_stage;
이슈 1 : IAM 앱 이름의 혼동
Snowflake에서 STORAGE INTEGRATION을 생성하면 Azure AD(Entra ID) 인증을 위한 앱 정보를 줍니다.
DESC STORAGE INTEGRATION my_azure_int;
-- 결과: AZURE_MULTI_TENANT_APP_NAME = 'zpjklz..._1767166889530'
문제 상황: Snowflake에서는 뒤에 숫자(_1767...)가 붙은 이름이 조회되는데, Azure에서는 숫자가 붙은 앱은 검색 안 되고, 숫자가 없는 zpjklz...만 보임
원인: Snowflake 내부적으로는 고유 식별을 위해 숫자를 붙여 관리하지만, Azure AD 상의 표시 이름은 숫자가 없는 공통 이름으로 생성되는 것이 정상입니다.
해결: 이름이 달라도 Client ID가 동일하므로, Azure에 보이는 숫자 없는 앱에 권한(Storage Blob Data Contributor)을 부여하면 정상 작동합니다.
이슈 2: 403 Forbidden 에러와 방화벽 설정
권한을 부여받고 LIST 명령어를 수행했으나 403 AuthorizationFailure가 발생했습니다.
원인: Private Link 환경이라 Storage Account의 방화벽이 닫혀 있었습니다.
해결: Snowflake VNet의 Subnet ID를 Azure Storage 방화벽의 Allow list에 등록해야 합니다.
-> Subnet ID는 Snowflake에서 SELECT SYSTEM$GET_SNOWFLAKE_PLATFORM_INFO();로 확인할 수 있습니다.
이슈 3: "Private endpoint does not exist" 에러
Error: SQL Execution Error: Private endpoint corresponding to service name ... does not exist.
원인: Snowflake는 Private Link 환경임을 감지하면, 기본적으로 스토리지 접근 시에도 Private Endpoint 경로를 찾으려 시도합니다. (USE_PRIVATELINK_ENDPOINT = TRUE가 기본 동작)
현황: 하지만 우리는 스토리지에 대해 Private Endpoint를 뚫은 게 아니라, Service Endpoint(Microsoft 백본망) 방식으로 방화벽만 열어둔 상태였습니다.
해결: Snowflake에서 Private Endpoint를 찾지 않도록 설정을 변경해야 합니다.
ALTER STORAGE INTEGRATION my_azure_int
SET USE_PRIVATELINK_ENDPOINT = FALSE;
'Snowflake' 카테고리의 다른 글
| [Snowflake] Snowflake World Tour Seoul 2025 참관 후기 (0) | 2025.11.04 |
|---|---|
| [Snowflake] MSSQL에서 Snowflake까지, CDC 파이프라인 구축 (0) | 2025.11.04 |
| [Snowflake] Container 기반 Notebook에 패키지 임포트시 오류 해결 (0) | 2025.11.04 |