[에러 해결] [Terraform Databricks] Service Principal 스키마 테이블 R/W 권한 부족 및 배포 자동화 해결 방법

안녕하세요, Databricks 환경에 Terraform을 사용하여 스키마 테이블을 배포하고 관리하시는 개발자 여러분! GitHub Actions와 같은 CI/CD 파이프라인을 통해 Terraform으로 Databricks 리소스를 자동화하는 과정에서, Service Principal의 권한 문제로 인해 스키마 테이블에 대한 읽기/쓰기(Read/Write) 권한을 부여하지 못하는 난감한 상황에 직면하는 경우가 많습니다.

특히 여러 워크스페이스에 걸쳐 배포하거나, 새로운 워크스페이스에 온보딩할 때 이러한 권한 관리는 더욱 복잡해집니다. 이 문서는 이러한 문제를 명확하게 분석하고, Terraform 코드를 통해 효과적으로 해결하는 방법을 제시하여 여러분의 Databricks 배포 자동화 여정을 더욱 원활하게 만들어 드리고자 합니다. 구글 검색 상위 노출에 최적화된 고품질 기술 문서로, 개발자 친화적인 설명을 담았습니다.

1. 에러 발생 상황

여러분은 GitHub 리포지토리에 Terraform 코드를 관리하며, 이를 활용하여 Databricks 워크스페이스에 스키마 테이블을 생성하고, 해당 테이블에 Service Principal 혹은 다른 사용자 그룹이 읽기/쓰기 권한을 가지도록 설정하려 합니다. 일반적으로 이러한 작업은 다음과 같은 시나리오에서 발생합니다.

  • Terraform으로 Databricks Unity Catalog 내에 카탈로그(Catalog) 및 스키마(Schema) 생성
  • 생성된 스키마 내에 테이블(Table) 정의 및 배포
  • CI/CD (예: GitHub Actions) 파이프라인에서 Terraform을 실행하여 Databricks 배포 자동화
  • 배포된 스키마 테이블에 특정 Service Principal 또는 사용자 그룹에게 SELECT, MODIFY 등의 읽기/쓰기 권한 부여 시도

이 과정에서 Terraform이 Service Principal의 자격으로 Databricks API를 호출하지만, 필요한 권한이 없어 스키마 테이블 생성 또는 권한 부여 작업이 실패하는 문제가 발생합니다. “권한을 요청해야 한다”는 식의 메시지를 받거나, 단순히 권한 부족 에러로 인해 Terraform apply가 실패할 수 있습니다.

2. 명확한 발생 원인

이러한 문제는 대부분 Terraform을 실행하는 Service Principal 또는 Databricks API 호출에 사용되는 자격 증명(Credential)에 Databricks 환경 내에서 리소스를 생성하고 권한을 관리할 수 있는 충분한 권한이 부여되지 않았기 때문입니다. 구체적인 원인은 다음과 같습니다.

  • 2.1. Service Principal의 권한 부족

    Terraform은 Databricks Provider를 통해 Databricks API와 상호작용합니다. 이때 인증에 사용되는 Service Principal은 Databricks 워크스페이스 내에서 카탈로그, 스키마, 테이블을 생성하고, 다른 주체에게 권한을 부여할 수 있는 충분한 권한을 가지고 있어야 합니다. 특히 Unity Catalog 환경에서는 권한 모델이 계층적(Metastore > Catalog > Schema > Table)이므로, 각 레벨에 맞는 권한이 필요합니다.

  • 2.2. Unity Catalog 권한 모델 이해 부족

    Databricks Unity Catalog는 강력한 데이터 거버넌스 기능을 제공하지만, 그만큼 엄격한 권한 모델을 따릅니다. 단순히 ‘Admin’ 권한만으로는 모든 작업을 수행할 수 없으며, Metastore, Catalog, Schema, Table 각 레벨에서 CREATE_CATALOG, CREATE_SCHEMA, USE_CATALOG, USE_SCHEMA, SELECT, MODIFY 등의 특정 권한이 명시적으로 부여되어야 합니다.

  • 2.3. Initial Provisioning 권한

    최초로 Databricks 워크스페이스를 설정하거나 Unity Catalog를 초기화할 때, 해당 작업을 수행하는 사용자 또는 Service Principal은 일반적으로 Account Admin 또는 Metastore Admin과 같은 높은 수준의 권한을 요구합니다. 이 권한이 없다면 이후의 Terraform 배포 작업에서 필요한 초기 권한을 부여할 수 없습니다.

  • 2.4. 잘못된 Terraform 리소스 사용

    Databricks Provider는 다양한 권한 관련 리소스를 제공합니다 (예: databricks_grants, databricks_access_control). 상황에 맞는 올바른 리소스를 사용하지 않거나, 문법을 잘못 작성할 경우 권한 부여에 실패할 수 있습니다.

3. 해결 방법 및 코드 예시

핵심은 Terraform을 실행하는 Service Principal에게 Databricks Unity Catalog 내에서 필요한 모든 권한을 명시적으로 부여하는 것입니다. 다음은 그 방법에 대한 단계별 설명과 코드 예시입니다.

3.1. Terraform 실행 Service Principal의 권한 확인 및 부여

먼저, Terraform을 실행할 Service Principal이 Databricks Unity Catalog에서 카탈로그, 스키마, 테이블을 생성하고 관리할 수 있는 권한을 가지고 있는지 확인해야 합니다. 만약 없다면, Databricks UI 또는 초기 Terraform 코드를 통해 이 Service Principal에게 해당 권한을 부여해야 합니다. 최소한의 초기 권한은 다음과 같습니다.

  • Metastore 레벨: CREATE_CATALOG (새로운 카탈로그 생성을 위해) 및 CREATE_EXTERNAL_LOCATION (외부 저장소 연동 시)
  • Workspace 레벨: CREATE_SERVICE_PRINCIPAL (다른 Service Principal 생성 시)

이러한 초기 권한은 일반적으로 Metastore Admin 또는 Account Admin 권한을 가진 사용자가 부여해야 합니다.

3.2. Terraform을 통한 Unity Catalog 권한 관리

필요한 Service Principal의 ID를 가져오고, databricks_grants 리소스를 사용하여 계층적으로 권한을 부여합니다.


# 1. Terraform을 실행할 Service Principal ID 가져오기 (만약 다른 SP에게 권한을 부여한다면 해당 SP의 ID)
data "databricks_service_principal" "deployer_sp" {
  display_name = "Your Terraform Deployer Service Principal Name" # 실제 Service Principal 이름
}

# 2. 새로운 카탈로그 생성
resource "databricks_catalog" "my_catalog" {
  name         = "my_data_catalog"
  comment      = "카탈로그 설명"
  owner        = data.databricks_service_principal.deployer_sp.display_name # 카탈로그 소유자 설정
  properties = {
    purpose = "testing"
  }
}

# 3. 카탈로그에 대한 권한 부여 (예: 해당 카탈로그를 사용할 수 있도록)
resource "databricks_grants" "catalog_grants" {
  catalog_name = databricks_catalog.my_catalog.name

  grant {
    principal  = data.databricks_service_principal.deployer_sp.display_name
    privileges = ["USE_CATALOG", "CREATE_SCHEMA"] # 카탈로그 사용 및 스키마 생성 권한
  }
}

# 4. 스키마 생성
resource "databricks_schema" "my_schema" {
  catalog_name = databricks_catalog.my_catalog.name
  name         = "my_schema"
  comment      = "스키마 설명"
  owner        = data.databricks_service_principal.deployer_sp.display_name # 스키마 소유자 설정
}

# 5. 스키마에 대한 권한 부여 (예: 해당 스키마를 사용할 수 있도록)
resource "databricks_grants" "schema_grants" {
  schema_name = databricks_schema.my_schema.id

  grant {
    principal  = data.databricks_service_principal.deployer_sp.display_name
    privileges = ["USE_SCHEMA", "CREATE_TABLE"] # 스키마 사용 및 테이블 생성 권한
  }
}

# 6. 테이블 생성 (예시: 더미 테이블)
resource "databricks_table" "my_table" {
  catalog_name = databricks_catalog.my_catalog.name
  schema_name  = databricks_schema.my_schema.name
  name         = "example_table"
  table_type   = "MANAGED" # 또는 "EXTERNAL"
  data_source_format = "DELTA"
  comment      = "예시 테이블"
  column {
    name = "id"
    type = "INT"
  }
  column {
    name = "name"
    type = "STRING"
  }
  owner        = data.databricks_service_principal.deployer_sp.display_name
}

# 7. 테이블에 대한 읽기/쓰기 권한 부여
resource "databricks_grants" "table_r_w_grants" {
  table_name = databricks_table.my_table.id # 테이블 전체 식별자 사용

  grant {
    principal  = data.databricks_service_principal.deployer_sp.display_name
    privileges = ["SELECT", "MODIFY"] # 테이블 읽기 및 수정 권한
  }

  # 만약 다른 Service Principal이나 그룹에게 권한을 부여하고 싶다면 추가
  # grant {
  #   principal  = "another_service_principal_id_or_group_name"
  #   privileges = ["SELECT"]
  # }
}

위 코드에서 data.databricks_service_principal.deployer_sp.display_name은 Terraform을 실행하는 Service Principal의 이름을 참조합니다. 이 Service Principal에게 카탈로그, 스키마, 테이블 생성 및 권한 부여에 필요한 모든 권한을 명시적으로 부여합니다. 중요한 것은 databricks_grants 리소스를 사용하여 필요한 권한을 정확한 주체(principal)와 함께 명시하는 것입니다.

3.3. GitHub Actions 워크플로우 예시

GitHub Actions에서 이 Terraform 코드를 실행하려면 Databricks 인증 정보를 환경 변수로 설정해야 합니다.


name: Terraform Databricks Deployment

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

jobs:
  terraform:
    name: "Terraform Apply"
    runs-on: ubuntu-latest
    environment: production # 환경 변수 관리를 위한 GitHub Environments 사용 권장

    steps:
      - name: Checkout Code
        uses: actions/checkout@v3

      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v2
        with:
          terraform_version: 1.4.x

      - name: Terraform Init
        id: init
        run: terraform init

      - name: Terraform Plan
        id: plan
        run: terraform plan -no-color
        env:
          DATABRICKS_HOST: ${{ secrets.DATABRICKS_HOST }}
          DATABRICKS_TOKEN: ${{ secrets.DATABRICKS_TOKEN }} # Service Principal의 Access Token

      - name: Terraform Apply
        id: apply
        if: github.ref == 'refs/heads/main' && github.event_name == 'push'
        run: terraform apply -auto-approve
        env:
          DATABRICKS_HOST: ${{ secrets.DATABRICKS_HOST }}
          DATABRICKS_TOKEN: ${{ secrets.DATABRICKS_TOKEN }}

DATABRICKS_HOST와 DATABRICKS_TOKEN은 GitHub Secrets에 안전하게 저장하여 사용해야 합니다. DATABRICKS_TOKEN에는 Terraform 배포용 Service Principal의 개인 액세스 토큰(PAT) 또는 OIDC 기반 인증을 위한 적절한 자격 증명을 설정해야 합니다.

4. 향후 예방을 위한 팁

  • 4.1. 최소 권한 원칙(Principle of Least Privilege) 준수

    Terraform을 실행하는 Service Principal에게 필요 이상의 권한을 부여하지 마십시오. 필요한 최소한의 권한만을 부여하고, 주기적으로 권한을 검토하여 보안 위험을 줄입니다.

  • 4.2. Unity Catalog 적극 활용

    Databricks Unity Catalog는 중앙 집중식 데이터 거버넌스를 위한 강력한 솔루션입니다. 가능한 한 Unity Catalog를 사용하여 카탈로그, 스키마, 테이블 및 해당 권한을 관리하면 복잡성을 줄이고 일관성을 유지할 수 있습니다.

  • 4.3. 환경별 Service Principal 분리

    개발, 스테이징, 프로덕션 등 각 환경에 대해 별도의 Service Principal을 생성하고 관리하는 것이 좋습니다. 이를 통해 환경 간의 격리성을 높이고, 특정 환경에서의 오류나 보안 문제가 다른 환경으로 전파되는 것을 방지할 수 있습니다.

  • 4.4. 코드화된 인프라(Infrastructure as Code, IaC)를 통한 권한 관리

    권한 부여 또한 Terraform 코드로 관리하여 버전 관리, 코드 리뷰, 자동화된 배포의 이점을 얻으세요. 이는 수동으로 권한을 설정하는 것보다 훨씬 일관되고 오류 발생 가능성이 적습니다.

  • 4.5. 공식 문서 참조

    Databricks와 Terraform의 공식 문서는 항상 최신 정보와 모범 사례를 제공합니다. 새로운 기능이나 변경 사항이 있을 때는 반드시 공식 문서를 참조하여 설정을 업데이트하는 것이 중요합니다.

이 문서를 통해 Databricks에 Terraform으로 스키마 테이블을 배포하고 Service Principal 권한을 관리하는 과정에서 겪는 어려움을 해결하는 데 도움이 되셨기를 바랍니다. 안정적인 Databricks 배포 파이프라인 구축에 성공하시길 응원합니다!

댓글 남기기