11.4 Code Versioning & Databricks Git Integration
Key Takeaways
- Databricks Git Integration (formerly Repos) allows you to sync Databricks Workspaces with remote Git providers like GitHub, GitLab, and Azure DevOps.
- Workspace Files allow non-notebook files (e.g., `.py`, `.yml`, `.csv`) to be stored, edited, and version-controlled directly within the Databricks UI.
- A standard deployment strategy involves isolating dev, staging, and prod environments using separate Databricks workspaces or isolated Git folders mapped to specific branches.
- Databricks Secret Scopes are used to securely manage credentials across environments without hardcoding API keys or passwords in version-controlled code.
- For production pipelines, code should never be edited directly in the production workspace; it must be deployed via CI/CD from the `main` or `release` branch.
Treating notebooks and scripts as ephemeral scratchpads is a dangerous anti-pattern. Professional data engineering requires strict code versioning, peer reviews, and secure credential management. Databricks provides native features to bridge the gap between traditional software engineering practices and the data platform. This section outlines enterprise strategies for code versioning using Databricks Git Integration, managing multi-environment repositories, and securing secrets.
Databricks Git Integration (Repos)
Databricks Git Integration (historically known as Repos) connects your Databricks workspace to remote Git repositories hosted on providers like GitHub, Bitbucket, GitLab, and Azure DevOps. This native integration ensures that data engineers do not have to leave the Databricks UI to commit code, pull changes, or resolve simple version control operations.
Capabilities of Git Integration
- Bi-directional Sync: You can clone a repository, edit code in Databricks, commit changes, and push them back to the remote provider directly from the UI or API. It supports standard Git operations including pull, commit, push, and branch switching.
- Branch Management: You can create new feature branches, switch between them, and pull the latest changes from the upstream branch. This allows multiple engineers to work on different features within their own isolated Git folders.
- Workspace Files: Git Integration seamlessly supports arbitrary files. You can store
.pymodules,.ymlconfiguration files, or.csvreference data alongside your notebooks. Crucially, you can import Python modules stored in the repository directly into your notebooks using standard Pythonimportstatements. This promotes code reuse and module-based design instead of massive, monolithic notebooks.
Structuring the Repository
A well-structured repository is critical for maintaining scalable Databricks projects. A recommended professional directory structure looks like this:
my-databricks-project/
├── .github/workflows/ # CI/CD pipeline definitions (GitHub Actions)
├── src/
│ ├── notebooks/ # Interactive Databricks notebooks
│ ├── modules/ # Reusable Python modules (.py)
│ └── sql/ # Raw SQL scripts for DLT or query execution
├── tests/
│ ├── unit/ # Pytest unit tests for local execution
│ └── integration/ # Integration tests running on Databricks clusters
├── conf/
│ └── cluster_config.json # Environment configurations
├── databricks.yml # Databricks Asset Bundle definition
├── requirements.txt # Python dependencies
└── README.md
By organizing code in this manner, automated testing tools and CI/CD pipelines can easily locate source code, tests, and configuration files. It also ensures that the databricks.yml file is at the root for easy discovery by the Databricks CLI.
Branching and Deployment Strategies
To ensure stability, organizations must enforce a strict branching strategy. The exam tests your ability to design workflows that isolate experimental development work from critical production workloads.
The Standard CI/CD Git Workflow
-
Development (Feature Branches):
- Developers create feature branches (e.g.,
feat/add-customer-agg) from themainbranch. - They link their personal Databricks Git folder to this feature branch in a Dev workspace.
- They write code, test interactively, commit their changes, and push to the remote Git provider.
- Developers create feature branches (e.g.,
-
Staging (Pull Requests):
- A Pull Request (PR) is opened against the
mainbranch. - A CI pipeline automatically triggers, running static analysis and unit tests on the PR code.
- A Staging Databricks Workspace Git folder is automatically updated via the Repos API to check out the PR branch, and an integration test job is triggered to validate the logic against staging data.
- A Pull Request (PR) is opened against the
-
Production (Main/Release Branch):
- Once the PR is approved and tests pass, it is merged into
main. - The CI/CD pipeline uses the REST API or
databricks bundle deployto push themainbranch code into the Production Workspace. - Crucial Rule: In the Production Workspace, the Git folder should be locked down (read-only), or code should be deployed purely as Workspace Files via bundles. No human engineer should ever have permissions to directly edit code in the production workspace.
- Once the PR is approved and tests pass, it is merged into
Environment Isolation
Isolation guarantees that experimental development code cannot accidentally drop production tables or consume massive production compute resources.
Workspace Isolation vs. Catalog Isolation
- Multi-Workspace Architecture (Recommended for Enterprise): Organizations provision distinct workspaces for Dev, Staging, and Prod. They share nothing except a centralized Unity Catalog metastore. This provides the highest level of security, precise cost-tracking per environment, and guaranteed compute isolation.
- Single Workspace / Catalog Isolation (For Smaller Teams): Everyone works in one workspace, but Unity Catalog is heavily leveraged to provide data isolation. Developers only have
USE CATALOGpermissions on thedev_catalog. The production Service Principal is the only entity with write access toprod_catalog. While this saves on infrastructure setup, it risks accidental compute contention if dev jobs consume all cluster capacity.
Managing Credentials with Secret Scopes
Code in a Git repository must never contain plain-text passwords, API tokens, or storage access keys. Because repositories are often cloned locally or exposed in CI/CD logs, hardcoding secrets is a massive security vulnerability that can lead to data breaches.
Databricks Secrets
Databricks provides the Secrets API to manage credentials safely.
- Creating a Scope: A secret scope is a logical container for secrets. It can be backed by Databricks locally, or backed by Azure Key Vault (on Azure Databricks) for enterprise-grade key management.
- Storing a Secret: You store key-value pairs (e.g.,
api_key: 12345ABC) inside the scope using the Databricks CLI or REST API. - Retrieving a Secret: Inside your notebook or code, you use Databricks Utilities to retrieve the secret at runtime. The value is redacted in standard output.
# Correct, secure way to access an API key
api_key = dbutils.secrets.get(scope="production_secrets", key="salesforce_api_key")
# The output will show [REDACTED] if printed
print(api_key)
Secrets Across Environments
To keep code DRY (Don't Repeat Yourself), use the exact same scope and key names in all environments, but populate them with different values in the respective workspaces.
For example, dbutils.secrets.get(scope="app_secrets", key="db_password") will return the dummy password when executed in the Dev workspace, and the real secure password when executed in the Prod workspace, all without requiring any code changes. This is the cornerstone of writing environment-agnostic code.
What is the primary benefit of using Workspace Files in conjunction with Databricks Git Integration?
According to best practices for production Databricks deployments, which of the following statements regarding the Production Workspace is correct?
How should a data engineer securely retrieve an API token within a Databricks notebook whose source code is stored in a Git repository?
An organization wants to use the same codebase across Dev, Staging, and Prod workspaces without modifying the source code. How can they seamlessly manage different database passwords for each environment?