OneLake과 Azure Blob Filesystem 연결
ABFS(Azure Blob Filesystem) 커넥터는 Microsoft OneLake, Azure Data Lake Storage Gen2와 호환되는 Azure 저장소의 파일을 Foundry로 수집하거나 Foundry 파일을 Azure에 기록합니다. Azure Data Lake Storage Gen1은 지원하지 않습니다.
원천 탐색, 대량 가져오기, 증분 수집, 미디어 집합, 가상 테이블과 파일 내보내기는 일반 제공 기능입니다. 이전 Export task는 Sunset 단계이며 기존 작업을 유지보수할 때만 사용합니다.
파일 모델과 실행 한도
모든 형식의 파일을 그대로 전송하며 수집 중이나 수집 직후에 스키마를 적용하지 않습니다. 정형 데이터로 사용하려면 출력 데이터셋에 스키마를 적용하거나 후속 변환에서 파일 내용을 읽습니다.
전송 가능한 파일 크기 자체에는 제한이 없지만 큰 전송은 네트워크 장애에 영향을 받습니다. Foundry 워커에서 이틀을 넘겨 실행하는 동기화는 중단됩니다. 파일 크기를 줄이고 실행당 수집 파일 수를 제한한 뒤 짧은 간격으로 예약하여 긴 단일 실행을 피할 수 있습니다.
기본 설정과 경로
Data Connection에서 + New Source를 선택하고 ABFS—Azure Data Lake Storage Gen2 소스를 선택합니다. 새 구성에는 직접 연결 정책을 사용하는 Foundry 워커를 권장합니다.
| 설정 | 필수 여부 | 의미 |
|---|---|---|
Root directory | 필수 | 데이터를 읽거나 기록할 루트 디렉터리입니다. |
Catalog | 선택 | 저장소의 가상 테이블에 사용할 카탈로그입니다. |
다음은 경로 구조를 설명하는 예시입니다. file_system, account_name과 디렉터리를 실제 값으로 바꿉니다.
abfss://file_system@account_name.dfs.core.windows.net/
abfss://file_system@account_name.dfs.core.windows.net/path/to/directory/
abfss://file_system@onelake.dfs.fabric.microsoft.com/path/to/directory/
첫 경로는 해당 파일시스템 전체, 두 번째는 ADLS Gen2 또는 Azure Blob Storage의 특정 디렉터리, 세 번째는 OneLake의 특정 디렉터리를 가리킵니다. Blob 엔드포인트인 .blob.core.windows.net 대신 DFS 엔드포인트인 .dfs.core.windows.net을 사용합니다.
SAS 토큰으로 Blob Storage에 접근할 때에는 Root directory에 디렉터리를 지정해야 하며 수집 내용은 그 디렉터리의 하위 폴더에 있어야 합니다.
수집 권한
커넥터는 파일시스템의 목록을 조회하고 파일 내용을 읽을 수 있어야 합니다.
- RBAC를 사용하면 데이터를 담은 컨테이너에
Storage Blob Data Reader역할을 부여합니다. - ACL만으로 권한을 부여하면 대상 파일에
Read, 컨테이너 루트부터 파일까지의 모든 상위 디렉터리에Execute가 필요합니다. 목록을 열거할 디렉터리에는Read와Execute가 모두 필요합니다.
원천의 인증 주체가 이 권한을 가지는지 확인합니다. 내보내기와 가상 테이블 출력에는 읽기 권한만으로 충분하지 않으므로 대상에 필요한 쓰기 권한도 준비합니다.
인증 방식
Client credentials
Foundry 직접 연결에는 Entra ID의 app registration과 서비스 주체를 사용하는 client credentials를 권장합니다.
| 설정 | 필수 여부 | 의미 |
|---|---|---|
Client endpoint | 필수 | 일반적인 형식은 https://login.microsoftonline.com/테넌트-ID/oauth2/token입니다. 경로의 식별자는 Directory(tenant) ID이며 Azure 구독 ID가 아닙니다. |
Client ID | 필수 | App registration의 Application(client) ID입니다. |
Client secret | 필수 | App registration에서 발급한 클라이언트 비밀 정보입니다. |
Shared access signature
SAS는 접근 범위와 유효기간을 제한한 토큰입니다. 이 커넥터의 Blob SAS token은 필수 입력이며 정적 토큰을 저장합니다. 만료되면 수동 갱신 전까지 동기화가 멈추므로 지속 운영에는 다른 인증 방식을 권장합니다.
일반적으로 컨테이너 수준 SAS를 사용합니다. Azure 포털의 해당 컨테이너에서 Settings > Shared access tokens로 생성합니다. 저장소 계정 수준 SAS가 필요한 경우 Security + networking > Shared access signature에서 최소한 다음 범위를 선택합니다.
| 설정 | 수집에 필요한 값 |
|---|---|
Allowed services | Blob |
Allowed resource types | Container, Object |
Allowed permissions | Read, List |
spr은 https로 제한하는 것을 권장합니다. sr은 서명한 리소스 종류를 나타내며 컨테이너는 c, 디렉터리는 d입니다. 디렉터리 범위 sr=d에는 sdd가 필요합니다. sdd는 서명한 디렉터리가 컨테이너 루트에서 몇 단계 아래에 있는지 나타냅니다. 루트는 0, /d1/d2는 2입니다. 하위 탐색을 더 허용하려는 목적으로 이 숫자를 임의로 크게 설정하지 않습니다.
다음은 형식 설명용으로 만료된 SAS 예시입니다. sp=r은 읽기 권한만 나타내며, 실제 커넥터 수집에서 필요한 목록 조회 권한과 유효한 서명을 대신하지 않습니다.
/container1/dir1?sp=r&st=2023-02-23T17:53:28Z&se=2023-02-24T01:53:28Z&spr=https&sv=2021-12-02&sr=d&sig=1gF9B%2FOnEmtYeDl6eB9tb0va1qpSBjZw3ZJuW2pMm1E%3D&sdd=1
사용자명과 비밀번호
OAuth 인증을 사용하며 테넌트에 해당하는 토큰 엔드포인트를 지정합니다.
| 설정 | 필수 여부 | 의미 |
|---|---|---|
Client endpoint | 필수 | 해당 테넌트의 OAuth 토큰 엔드포인트입니다. |
Username | 필수 | 사용자의 이메일 주소입니다. |
Proxy password | 필수 | 이 인증 구성에서 요구하는 비밀번호 토큰입니다. |
Refresh token
| 설정 | 필수 여부 | 의미 |
|---|---|---|
Client ID | 필수 | Microsoft Entra ID 애플리케이션의 클라이언트 ID입니다. |
Refresh Token | 필수 | 새 액세스 토큰을 발급받는 갱신 토큰입니다. |
Shared key
Azure 저장소 계정은 두 개의 공유 키를 제공합니다. 이 방식의 필수 항목은 Account key이며 Azure 포털의 저장소 계정에서 Security + networking > Access keys로 확인합니다.
공유 키는 컨테이너보다 넓은 저장소 계정 범위의 권한을 가지며 수동으로 교체해야 합니다. 운영 연결에는 권장하지 않습니다.
Workload Identity Federation
OIDC 기반 워크로드 신원 연합을 사용할 수 있습니다. Tenant ID와 Client ID가 모두 필수입니다. Foundry 소스 화면에 제시되는 원천 구성값으로 Azure 측 연합 신뢰를 설정합니다. 정적 공유 키 방식과 달리 OIDC 신뢰에 따라 인증합니다.
Azure managed identity: 기존 에이전트 워커
이 인증은 Legacy 에이전트 워커 소스에만 사용할 수 있습니다. 새 소스에는 client credentials를 사용합니다. 인증 정보를 Foundry에 저장할 필요는 없지만 VM에 할당한 관리형 신원에 저장소 접근 권한이 있어야 합니다.
Tenant ID와 Client ID는 선택 항목입니다. VM에 여러 관리형 신원이 할당되어 있으면 저장소 연결에 사용할 신원을 Client ID로 지정합니다. 에이전트는 같은 Azure 테넌트의 VM에서 실행되어야 합니다. 관리형 신원 토큰 엔드포인트는 해당 VM의 모든 프로세스에서 접근할 수 있으므로 VM 자체가 보안 경계입니다.
네트워크 양쪽 설정
- Foundry의 외부 통신 정책에서 저장소 도메인의 HTTPS
443포트를 허용합니다. 예를 들어abfss://file_system@account_name.dfs.core.windows.net/의 도메인은account_name.dfs.core.windows.net입니다. Data Connection은 입력한 연결 정보에 맞는 정책을 제안합니다. - Azure 저장소 계정에서도 선택한 연결 경로를 허용합니다. 공용 IP 경로에서는 Control Panel의
Network Egress에 표시된 Foundry 출발 IP를 사용합니다. Azure Storage 정책 경로에서는 Foundry subnet을 허용합니다.
Azure에 호스팅된 Foundry는 저장소와 같은 리전에서도 Azure Storage 네트워크 정책을 사용할 수 있습니다. Control Panel의 Azure Storage policies에 저장소를 등록하고, 저장소의 VNet 규칙에서 Foundry subnet을 허용하며, 별도의 외부 통신 정책도 소스에 연결합니다. 조직 정책이 Private Link를 요구하거나 subnet 허용 방식이 적합하지 않으면 Azure Private Link를 구성합니다. 네트워크 허용과 별개로 저장소 인증은 계속 필요합니다.
파일 동기화와 내보내기
수집은 파일 기반 동기화 인터페이스에서 경로와 대상 파일을 선택합니다. 파일 형식을 보존한 상태로 가져오므로 후속 읽기와 스키마 적용을 별도로 구성합니다.
새 내보내기는 소스에서 내보내기를 활성화한 다음 파일 내보내기를 생성합니다. 아래 Export task 설정은 기존 작업의 유지보수에 해당합니다.
기존 Export task
소스가 있는 프로젝트 폴더에서 커넥터를 우클릭하고 Create Data Connection Task로 작업을 구성하던 방식입니다. 작업의 Source를 확인하고 inputDataset 입력과 outputDataset 출력을 구분합니다. 입력은 Azure로 보낼 데이터셋, 출력은 작업 실행, 예약과 모니터링에 사용하는 데이터셋입니다. 왼쪽 패널에 표시되는 레이블은 YAML 이름을 반영하지 않을 수 있습니다.
| 설정 | 필수 여부 | 의미 |
|---|---|---|
directoryPath | 필수 | 출력 디렉터리이며 끝에 /가 있어야 합니다. |
excludePaths | 선택 | 파일 이름이 일치하면 내보내지 않는 정규식 목록입니다. |
rewritePaths | 선택 | 파일 이름의 일치 부분과 캡처 그룹을 치환합니다. |
uploadConfirmation | 선택 | exportedFiles로 설정하면 출력 데이터셋에 내보낸 파일 목록을 기록합니다. |
createTransactionFolders | 선택 | Foundry 트랜잭션마다 고유 하위 폴더를 만듭니다. 이름은 해당 트랜잭션의 Foundry 커밋 시각을 기준으로 합니다. |
incrementalType | 선택 | incremental이면 이전 내보내기 이후에 발생한 트랜잭션만 내보냅니다. |
flagFile | 선택 | 빌드의 파일 전송이 완료되었음을 알리는 빈 파일을 구성합니다. |
spanMultipleViews | 선택 | true이면 한 빌드에서 여러 트랜잭션을 내보내고, false이면 하나만 내보냅니다. 증분 방식에서는 가장 오래된 미처리 트랜잭션부터 보냅니다. |
이름 치환
rewritePaths에서 파일 이름에 일치하는 키의 정규식과 캡처 그룹을 값으로 치환합니다. 치환값에는 다음 메타데이터를 넣을 수 있습니다.
| 표현 | 치환값 |
|---|---|
${dt:javaDateExpression} | 파일을 내보내는 시각입니다. Java DateTimeFormatter 패턴을 사용합니다. |
${transaction} | 파일이 속한 Foundry 트랜잭션 ID입니다. |
${dataset} | 파일이 속한 Foundry 데이터셋 ID입니다. |
가상 예시로 spark/file_name, 트랜잭션 transaction_id, 데이터셋 dataset_id에 키 fi.*ame과 값 file_${dt:DD-MM-YYYY}-${transaction}-${dataset}_end를 사용하면 해당 예시 시각의 결과는 다음과 같습니다.
spark/file_79-03-2023-transaction_id-dataset_id_end
완료 표시 파일
flagFile은 한 빌드의 데이터 복사가 모두 끝난 뒤 기록하는 빈 파일입니다. 기본 위치는 directoryPath이고 createTransactionFolders를 사용하면 데이터를 기록한 하위 폴더마다 만듭니다. 예를 들어 이름을 confirmation.txt로 지정하면 모든 데이터 파일을 내보낸 뒤 각 폴더의 표시 파일을 한꺼번에 기록합니다. 개별 하위 폴더의 전송이 끝났다는 이유만으로 먼저 기록하지 않습니다.
Azure의 데이터 파일이 표시 파일보다 최신이면 이전 내보내기가 실패했거나 해당 폴더의 내보내기가 진행 중일 수 있습니다. 작업 구성을 변경한 뒤 Save로 저장합니다.
ABFS 가상 테이블
가상 테이블은 파일을 Foundry 데이터셋으로 복사하는 동기화와 달리 Azure에 있는 테이블을 가리킵니다.
| 기능 | 지원 범위 |
|---|---|
| 대량 등록과 자동 등록 | 지원하지 않습니다. |
| 테이블 입력과 출력 | Code Repositories와 Pipeline Builder에서 Avro, Delta, Iceberg, Parquet을 일반 제공합니다. |
| 증분 파이프라인 | Delta와 Iceberg의 APPEND를 지원합니다. Parquet은 지원하지 않습니다. |
| 저장소로 연산 위임 | 지원하지 않습니다. |
Foundry 워커가 필요하고 에이전트 워커는 사용할 수 없습니다. 네트워크 양쪽 허용을 설정하며 인증은 client credentials, username/password, workload identity federation 중 하나를 사용해야 합니다. 다른 인증 방식은 가상 테이블에 지원하지 않습니다. Code Repositories에서 사용할 때에는 소스를 가져오고 관련 코드 사용 및 내보내기 권한도 설정합니다.
Delta
증분 파이프라인에는 원천 Delta 테이블의 Change Data Feed를 활성화해야 합니다. Python 변환에서 current와 added 읽기 모드를 지원하며 _change_type, _commit_version, _commit_timestamp 열을 사용할 수 있습니다. 지원되는 증분 변경은 append-only입니다.
Iceberg 카탈로그
같은 소스에 등록하는 Iceberg 테이블은 같은 카탈로그를 사용해야 합니다. Object Storage 방식에서는 메타데이터 파일이 있는 위치를 warehousePath로 지정합니다.
Unity Catalog는 Databricks의 Delta UniForm과 함께 사용할 수 있습니다. 기존 연결에서는 소스의 Connection details에 endpoint와 개인 액세스 토큰을 구성하고 catalog_name.schema_name.table_name 형식으로 테이블을 등록합니다. ABFS 소스의 Unity Catalog 연결은 Legacy 방식이므로 새 구성에는 Databricks 소스를 권장합니다.
Azure Data Lake Storage Gen2의 Iceberg 테이블에는 Polaris도 사용할 수 있으며 Connection details에서 카탈로그를 구성합니다.
Iceberg 증분 지원은 Incremental Reads에 의존하며 append-only입니다. Python 변환에서는 current와 added를 지원합니다.
Parquet
Parquet 가상 테이블은 스키마를 추론할 때 최대 100개 파일을 읽습니다.
오류별 점검
| 오류 또는 증상 | 확인할 내용 |
|---|---|
The resource does not support specified HTTP verb HEAD | .blob.core.windows.net 대신 .dfs.core.windows.net의 ABFS 경로를 사용했는지 확인합니다. |
This endpoint does not support BlobStorageEvents or SoftDelete..., 409, HEAD | 해당 ABFS 경로와 계정 기능의 호환성 문제입니다. 이 오류가 발생하는 구성에서는 SoftDelete 비활성화가 해결책이 될 수 있으나 저장소의 데이터 보호 설정이므로 관리자가 보호 요건과 영향을 확인한 뒤 변경해야 합니다. |
AADToken: HTTP connection failed for getting token from AzureAD, 401 Unauthorized | Data Connection UI의 client credentials 설정에서 비밀 정보에 +나 /가 포함될 때 발생하는 알려진 문제가 있습니다. 이 문제에 해당하면 두 문자가 없는 새 자격 증명으로 교체하고 계속 실패하면 Palantir 담당자에게 문의합니다. 모든 401 오류의 원인이 이 문제인 것은 아닙니다. |
같은 AADToken 오류의 400 Bad Request, managed identity 사용 중 | VM의 메타데이터 엔드포인트 상태와 관리형 신원 연결 여부를 확인합니다. |
<!DOCTYPE html>로 시작하는 HTML 504 gateway timeout | Foundry와 에이전트 VM 사이, VM과 원천 사이의 프록시를 확인합니다. ABFS 플러그인은 자체 프록시 설정을 관리하지 않고 에이전트 설정에 의존합니다. 에이전트가 정상이고 VM 터미널에서 파일 접근도 가능하면 지원을 요청합니다. |
This request is not authorized to perform this operation using this resource type., 403, HEAD | SAS의 리소스 범위와 권한을 확인합니다. 전체 소스 미리보기는 성공해도 좁은 경로 필터를 적용한 미리보기가 실패할 수 있습니다. |
export-abfs-task가 root/opt/palantir/magritte-bootvisor/var/data/processes/bootstrapper/ 아래에 기록 | 출력 디렉터리 URL 끝에 /가 있는지 확인합니다. DFS 호스트도 사용해야 합니다. |
경로 형식의 차이는 다음 가상 예시와 같습니다.
abfsRootDirectory: 'abfss://example-container@exampleaccount.dfs.core.windows.net/'
파일시스템 이름을 포함하고 DFS 호스트를 사용하며 끝의 /를 유지합니다.
에이전트 VM에서 managed identity 분리 진단
Legacy 에이전트 워커의 인증과 네트워크 문제를 구분하려면 에이전트가 실행되는 Azure VM에서 직접 토큰을 받고 저장소를 조회할 수 있습니다. 관리형 신원이 할당되어 있고 해당 파일에 읽기 권한이 있어야 합니다. IMDS 토큰 엔드포인트는 VM의 일반 IP가 아닌 169.254.169.254입니다.
다음은 VM에서 실행하는 독립 Python 진단 스크립트이며 Code Repositories 변환이 아닙니다. Python과 requests를 준비하고 상수의 저장소 계정, 파일시스템과 파일 경로를 실제 값으로 수정합니다. 여러 사용자 할당 신원 중 하나를 선택해야 하면 MANAGED_IDENTITY_CLIENT_ID를 그 신원의 client ID로 지정합니다. 단일 신원에서는 None을 사용합니다.
from urllib.parse import quote
import requests
STORAGE_ACCOUNT = "exampleaccount"
FILESYSTEM = "example-container"
FILE_PATH = "path/to/file.txt"
MANAGED_IDENTITY_CLIENT_ID = None
params = {
"api-version": "2018-02-01",
"resource": "https://storage.azure.com/",
}
if MANAGED_IDENTITY_CLIENT_ID is not None:
params["client_id"] = MANAGED_IDENTITY_CLIENT_ID
with requests.Session() as metadata_client:
metadata_client.trust_env = False
token_response = metadata_client.get(
"http://169.254.169.254/metadata/identity/oauth2/token",
params=params,
headers={"Metadata": "true"},
timeout=30,
)
token_response.raise_for_status()
token = token_response.json()["access_token"]
base_url = f"https://{STORAGE_ACCOUNT}.dfs.core.windows.net/{quote(FILESYSTEM, safe='')}"
headers = {"x-ms-version": "2018-11-09", "Authorization": f"Bearer {token}"}
listing = requests.get(
base_url,
params={"resource": "filesystem", "recursive": "false"},
headers=headers,
timeout=30,
)
listing.raise_for_status()
print(listing.text)
file_response = requests.get(
base_url + "/" + quote(FILE_PATH, safe="/"),
headers=headers,
timeout=30,
)
file_response.raise_for_status()
print(file_response.text)
토큰은 메모리에만 두고 출력하거나 명령줄 인자로 전달하지 않습니다. 스크립트가 출력하는 것은 파일시스템 목록 응답과 선택한 텍스트 파일의 내용입니다. 목록 응답 한 번을 확인하는 진단이며 큰 파일시스템의 모든 페이지를 수집하는 동기화 구현은 아닙니다.