我们有一个 Azure Databricks 工作区和开发/QA/生产环境。每次数据工程师必须从非产品 -> 产品(例如 python 笔记本、配置模块等)发送工件时,他们必须手动将工件复制到下一个环境并更改配置文件中的路径,以便在新环境中正常工作环境。
这很麻烦,他们看到了通过利用 Azure DevOps 管道来减少辛苦工作的机会。
我们如何围绕此创建管道来迁移这些工件?最佳做法是什么?例如,我们考虑使用 Azure Keyvault 来存储变量特定环境并通用化配置路径,以便在管道运行时动态替换它们。但这真的是最好的方法吗?有没有更好的方法,也许现在有新方法可以更轻松地做到这一点?类似的事情就是我在这里试图理解的,以便在 2024 年以最好的方式做到这一点。
这是当前设置的示例 databricks 工作区结构以及示例配置文件,其中包含硬编码路径,这些路径始终必须针对新环境配置进行更改。
Databricks 工作区结构:
工作区
->共享
-->演示
-->指标引擎
-->模块
--->_资源
--->测试
--->示例.ipynb
--->mod_config.ipynb
--->mod-schema.ipynb
mod_config.ipynb
有一些像这样的硬编码开发路径(它们以“abfss”开头):
config = {
ConfigurationKeys.ROOT_PATH + Constants.FileFormats.CSV: ConfigEntry(None, 'abfss://companyxyzanalyticsdev@companyxyzdatageneraldev.dfs.core.windows.net/source/companyxyz/extracts/sampledb'),
ConfigurationKeys.ROOT_PATH + Constants.FileFormats.PARQUET: ConfigEntry(None, 'abfss://companyxyzanalyticsdev@companyxyzdatageneraldev.dfs.core.windows.net/sink/tables/parquet/'),
ConfigurationKeys.OUTPUT_PATH: ConfigEntry(None, 'abfss://[email protected]/data-projects/internal/data-regression-analysis/resultset'),
ConfigurationKeys.RELATIVE_PATH_DATALAKE_TABLES_TRANSACTIONS: ConfigEntry(Constants.FileFormats.CSV, DataLake.RelativePaths.SourceTables.Transactions),
ConfigurationKeys.RELATIVE_PATH_DATALAKE_TABLES_REGIONS: ConfigEntry(Constants.FileFormats.CSV, DataLake.RelativePaths.SourceTables.Regions),
.............
因此,理想情况下,在管道运行时,路径最终将更改为 QA 路径和 Prod 路径,因为现在您可以看到它们是特定于开发人员的,通常在将它们手动复制到其他环境后必须手动更新它们,正如前面提到的那样麻烦了!所以也许如果有一个可以在笔记本中完成的转换,或者如果路径必须变得通用并且特定的必须存储在 keyvault 中,等等。无论最好的方法是什么。
仅供参考,databricks 存储库托管在 bitbucket 中(尽管如有必要,可以更改为 Azure Repos,并使事情变得更容易,但开发人员非常习惯 bitbucket)
我还检查了这个线程,但它使用 terraform 来尝试更新参数。我们不使用 terraform...但是,如果我们毕竟不得不求助于 IaC,我们可以根据需要集成 Bicep。
我还遇到了 this repo 示例,尽管它使用 github 集成,但我们不想使用 github。也不确定是否按照 2024 年最佳实践实施
如何将 Databricks 工件从一种环境迁移到另一种环境并在管道运行时更改配置路径?
我认为你的方向是正确的。在部署到databricks之前,您需要替换管道中不同环境之间的配置路径。
由于示例文件 mod_config.ipynb 中有硬编码路径,因此您可以使用 PowerShell 脚本来替换该值。
下面的脚本是搜索
single quote
之间并以 abfss
开头的所有字符串,替换出现的 1st
、2nd
、3rd
的值。 You can add more if needed
。
variables:
- group: VG2
steps:
- task: PowerShell@2
inputs:
targetType: 'inline'
script: |
$fileContent = Get-Content -Path modules/mod_config.ipynb
echo $fileContent
$pattern = "(?<=')abfss[^']*(?=')"
$count = 0
$fileContent | ForEach-Object {
if ($_ -match $pattern) {
$count++
if ($count -eq 1) {
$_ -replace $pattern, "$(var1)" # the variable from group
} elseif ($count -eq 2) {
$_ -replace $pattern, "$(var2)"
} elseif ($count -eq 3) {
$_ -replace $pattern, "$(var3)"
} else {
$_
}
} else {
$_
}
} | Set-Content -Path modules/mod_config.ipynb
- task: PublishPipelineArtifact@1
inputs:
targetPath: '$(Pipeline.Workspace)/s'
artifact: 'test'
publishLocation: 'pipeline'
我发布工件来检查文件内容,
each
值已正确替换为不同的变量值。
您可以在
different variable groups
中定义different stages(environment)
,这样它就会相应地替换该值。
stages:
- stage: Dev # first stage/environment
variables:
- group: VG2 # first variable group
jobs:
- job: A1
pool:
name: wadepool
steps:
- ..... # the tasks to replace config paths and databricks deploy
- stage: Prod # 2nd stage/environment
variables:
- group: VG3 # 2nd variable group
jobs:
- job: B1
pool:
name: wadepool
steps:
..... # the tasks to replace config paths and databricks deploy
或者你可以在
#{placeholder}#
中使用mod_config.ipynb
(占位符名称与变量名称相同),并使用扩展任务replacetokens@6来替换不同阶段之间的值,也可以。
stages:
- stage: Dev
variables:
- group: VG2
jobs:
- job: A1
pool:
name: wadepool
steps:
- task: replacetokens@6
inputs:
sources: '**\mod_config.ipynb'
- task: PublishPipelineArtifact@1
inputs:
targetPath: '$(Pipeline.Workspace)/s'
artifact: 'test2'
publishLocation: 'pipeline'
... your databricks tasks...
- stage: Prod
variables:
- group: VG3
jobs:
- job: B1
pool:
name: wadepool
steps:
- task: replacetokens@6
inputs:
sources: '**\mod_config.ipynb'
... your databricks tasks