Snowflake DCM 与 GitHub CI/CD 部署指南
有效阅读仅保存在当前浏览器,用于「为你」推荐;暂停或清除记录。
DataHot 速览
文章介绍如何将 Snowflake Database Change Management(DCM)与 GitHub Actions CI/CD 结合,用于管理数据库定义在 DEV、QA、PROD 环境间的流转。GitHub 负责协作与审批,Actions 执行部署,DCM 管理期望的数据库定义。流程强调变更需经过审查、测试和批准后才能进入下一环境,以实现职责分离并避免手动部署。
为什么值得关注:面向数据平台团队,讲清 Snowflake 数据库变更管理如何与 GitHub CI/CD 结合,以及审批、环境流转和职责分离的落地方式,对建设可审计的部署流程有参考价值。
本文目录 14 节
译文
AI 逐段翻译每个团队都希望部署更快。但当你管理生产数据库时,缺乏控制的速度很快会变成问题。部署数据库变更曾经很简单,但要确切知道生产环境里部署了什么、是否经过批准、是否经过了正确的环境,则完全是另一回事。
在我们的第一篇指南中,我们解决了保持 Snowflake 环境对齐的挑战,而让数据库定义受控只是战斗的一半。我们仍然需要弄清楚如何将变更从 DEV 迁移到 QA,最终迁移到 PROD,同时不让部署变成手动操作。
当我们转向 Snowflake Database Change Management (DCM) 时,GitHub CI/CD 流水线应运而生,我们需要一个可靠的流程来将这些定义推进到各个环境中。随着多名开发人员在我们的 Snowflake 数据库上贡献代码,我们需要一个既可靠又能推进变更而不失去控制的部署流程。
在 DEV 中做出的变更不应仅仅因为有人认为它已就绪,就自行进入 QA 和 PROD。它需要经过审查、测试和批准,才能进入下一个环境。
我们还希望避免在缺乏足够可见性的情况下部署变更,或有人引入未经团队其他成员审查的变更。
GitHub 为我们提供了协作和审批层,而 GitHub Actions CI/CD 流水线处理了我们的部署工作流。DCM 提供了管理我们所需数据库定义的机制。
这些组件共同为我们提供了更清晰的职责分离:开发人员提出变更,审查者批准变更,流水线将已批准的部署定义部署到相关环境。
我们为何搭建 GitHub CI/CD 流水线
我们希望开发人员快速推进,同时不损害生产环境的稳定性。
开发人员应该能够在 DEV 中创建表、修改视图或更新数据库定义,而无需在 QA 和 PROD 中手动重复相同的部署步骤。
同时,我们不希望每个开发人员都对生产部署拥有不受限制的控制权。我们寻找一个能为我们提供三样东西的流程:
- 一致性:同一个受版本控制的 DCM 项目将通过我们的各个环境进行部署。
- 自动化:部署和验证将自动运行,而非依赖手动执行 Snowflake CLI 命令。
- 治理:生产变更在合并和部署前需要获得批准。
我们的 GitHub CI/CD 流水线工作流
我们预期的工作流很简单:功能分支 → DEV → QA → 拉取请求审批 → PROD 有趣的部分在于我们如何使用 GitHub 和 Snowflake CLI 连接这些阶段。
我们的工作流遵循三个阶段:
- DEV——开发和验证。开发人员对 DCM 项目进行变更,将其提交到版本控制,并创建合并请求以供审查。
- QA——测试和验证。已批准的变更部署到 QA,我们可以在那里验证最终的数据库状态,并确认变更按预期表现。
- PROD——受控发布。一旦 QA 验证完成、所需批准齐全且流水线通过,变更即可通过受控部署流程提升到生产环境。
引入合并请求审批为开发流程增加了一个步骤。如果审查者不可用,变更可能需要更长时间才能推进,而配置不当的分支保护可能造成不必要的瓶颈。
然而,我们认为对于面向共享 QA 和生产环境的变更来说,这种权衡是值得的。目标并非为了官僚主义而引入审批,而是让数据库部署可追踪、可重复,并受到适当程度的审查。
设置
本指南将引导我们使用 GitHub Actions 和 Snowflake OIDC 身份验证配置自动化部署。
先决条件
- 具有 ACCOUNTADMIN 角色的 Snowflake 账户
- 已设置 DCM 项目(参见 01-dcm-project-setup)
- 连接到 Snowflake 工作区的 GitHub 仓库
- Snowflake CLI (snow) 版本 3.24+
1.1 在 Snowflake 中创建 OIDC 服务用户
需要两个服务用户,因为 GitHub 为拉取请求与推送到 main 发送的 OIDC 主题不同。
-- User for PROD deployments (triggered on push to main)
CREATE USER IF NOT EXISTS GITHUB_ACTIONS_SERVICE_USER
TYPE = SERVICE
DEFAULT_ROLE = ACCOUNTADMIN
DEFAULT_WAREHOUSE = COMPUTE_WH
COMMENT = 'Service user for GitHub Actions - push to main';
GRANT ROLE ACCOUNTADMIN TO USER GITHUB_ACTIONS_SERVICE_USER;
-- User for DEV/QA deployments (triggered on pull requests)
CREATE USER IF NOT EXISTS GITHUB_ACTIONS_PR_USER
TYPE = SERVICE
DEFAULT_ROLE = ACCOUNTADMIN
DEFAULT_WAREHOUSE = COMPUTE_WH
COMMENT = 'Service user for GitHub Actions - pull requests';
GRANT ROLE ACCOUNTADMIN TO USER GITHUB_ACTIONS_PR_USER;1.2 添加 GitHub 仓库机密
前往: https://github.com/your-org/your-repo/settings/secrets/actions
添加这些机密: 机密名称:SNOWFLAKE_ACCOUNT 值:你的组织限定账户(例如 ‘IJETSTR-TQ717873’)
注意:无需用户机密——OIDC 自动处理身份。
1.3 创建 GitHub Actions 工作流文件
.github/workflows/dcm-plan.yml(PR 上的 DEV + QA)
当针对 main 打开 PR 时,这会部署到 DEV 和 QA。两者都必须通过,PR 才能合并。
name: DCM Deploy DEV & QA
on:
pull_request:
branches: [main]
permissions:
id-token: write
contents: read
jobs:
deploy-dev:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: snowflakedb/snowflake-actions@v3
with:
use-oidc: true
cli-version: "3.24"
- name: Configure Snowflake connection
run: |
mkdir -p ~/.snowflake
cat > ~/.snowflake/connections.toml << EOF
[default]
account = "${{ secrets.SNOWFLAKE_ACCOUNT }}"
authenticator = "WORKLOAD_IDENTITY"
role = "ACCOUNTADMIN"
warehouse = "COMPUTE_WH"
EOF
chmod 0600 ~/.snowflake/connections.toml
- name: DCM Plan - DEV
run: snow dcm plan --target DEV -c default
- name: DCM Deploy - DEV
run: snow dcm deploy --target DEV --alias "pr-${{ github.event.number }}" -c default
deploy-qa:
runs-on: ubuntu-latest
needs: deploy-dev
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: snowflakedb/snowflake-actions@v3
with:
use-oidc: true
cli-version: "3.24"
- name: Configure Snowflake connection
run: |
mkdir -p ~/.snowflake
cat > ~/.snowflake/connections.toml << EOF
[default]
account = "${{ secrets.SNOWFLAKE_ACCOUNT }}"
authenticator = "WORKLOAD_IDENTITY"
role = "ACCOUNTADMIN"
warehouse = "COMPUTE_WH"
EOF
chmod 0600 ~/.snowflake/connections.toml
- name: DCM Plan - QA
run: snow dcm plan --target QA -c default
- name: DCM Deploy - QA
run: snow dcm deploy --target QA --alias "pr-${{ github.event.number }}" -c default.github/workflows/dcm-deploy.yml(合并到 main 时部署到 PROD)
仅在代码合并到 main 后(即 DEV 和 QA 通过后),才会部署到 PROD。
name: DCM Deploy PROD
on:
push:
branches: [main]
permissions:
id-token: write
contents: read
jobs:
deploy-prod:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: snowflakedb/snowflake-actions@v3
with:
use-oidc: true
cli-version: "3.24"
- name: Configure Snowflake connection
run: |
mkdir -p ~/.snowflake
cat > ~/.snowflake/connections.toml << EOF
[default]
account = "${{ secrets.SNOWFLAKE_ACCOUNT }}"
authenticator = "WORKLOAD_IDENTITY"
role = "ACCOUNTADMIN"
warehouse = "COMPUTE_WH"
EOF
chmod 0600 ~/.snowflake/connections.toml
- name: DCM Plan - PROD
run: snow dcm plan --target PROD -c default
- name: DCM Deploy - PROD
run: snow dcm deploy --target PROD --alias "gh-${{ github.sha }}" -c default2.1 更新 OIDC 服务用户
注意:我们初次运行工作流时,会从 GitHub 错误消息中获取实际值来更新服务用户主题,并在下面的 ALTER USER 语句中使用它们,例如 subject 'repo:tawandalloyd@51161179/ACME_REPO@1327244470:ref:refs/heads/main'(用于部署)和 subject 'repo:tawandalloyd@51161179/ACME_REPO@1327244470:ref:pull_request'(用于 PR)
-- Set OIDC trust for push-to-main events
ALTER USER GITHUB_ACTIONS_SERVICE_USER SET
WORKLOAD_IDENTITY = (
TYPE = OIDC
ISSUER = 'https://token.actions.githubusercontent.com'
SUBJECT = 'repo:your-username@OWNER_ID/your-repo@REPO_ID:ref:refs/heads/main'
);
-- Set OIDC trust for pull request events
ALTER USER GITHUB_ACTIONS_PR_USER SET
WORKLOAD_IDENTITY = (
TYPE = OIDC
ISSUER = 'https://token.actions.githubusercontent.com'
SUBJECT = 'repo:your-username@OWNER_ID/your-repo@REPO_ID:pull_request'
);3 配置分支保护
前往: https://github.com/your-org/your-repo/settings/branches
- 点击 添加分支保护规则
- 分支名称模式:main
- 启用: 合并前需要拉取请求 (阻止直接推送)
- 保存
4 开发工作流
一切配置完成后,日常工作流是:
- 在 Snowsight 工作区创建功能分支 Git 面板 → 创建分支 → 例如 “BN-0001_AddMembersTable”
- 修改定义文件 在我们的定义文件中创建一个新的 members 表。通过 Snowsight 中的 Git 面板提交并推送更改
- 在 GitHub 上向 main 打开 PR GitHub 将显示“比较并拉取请求”按钮
- GitHub Actions 自动: 创建拉取请求后,GitHub Actions 将创建一个部署计划,把我们的更改部署到我们的环境 部署到 DEV ✅ 部署到 QA ✅(在 DEV 通过后)
在我们的部署在 Dev 和 QA 中通过后,我们可以合并 PR
- GitHub Actions 自动: 当我们合并拉取请求时,使用 CI/CD 将我们的最新更改部署到 PROD ✅
5 故障排除
我们在设置 CI/CD 管道时可能遇到的常见问题有:
- OIDC 主体不匹配 如果你看到“subject was not recognized”,请从错误中复制准确的主体并更新 Snowflake 用户:
ALTER USER GITHUB_ACTIONS_SERVICE_USER SET
WORKLOAD_IDENTITY = (
TYPE = OIDC
ISSUER = 'https://token.actions.githubusercontent.com'
SUBJECT = '<exact-subject-from-error>'
);- LOGIN_NAME 错误 如果你看到“LOGIN_NAME should not be specified”,请确保你的 connections.toml 中没有 user 字段。WORKLOAD_IDENTITY 会根据令牌识别用户。
- 权限警告 如果你看到“Bad owner or permissions on connections.toml”,请确保在创建工作流中的文件后执行 chmod 0600。
- 分支保护阻止合并 如果状态检查未出现在下拉列表中,它们需要至少运行一次。暂时禁用“Require status checks”,进行合并,然后重新启用。
最终思考
在 DEV、QA 和 PROD 之间管理数据库更改,并不仅仅是让三个环境保持运行的问题。而是要确保我们的更改能够跨环境进行,同时不丢失一致性、可追溯性和控制力。
将 Snowflake DCM 与 GitHub CI/CD 相结合,为我们提供了一种实用方式,让我们的数据库更改遵循我们开发团队所习惯的软件交付实践。
我们真正的价值不在于管道自动执行部署命令,而在于我们如何定义所引入的更改、验证我们的更改,并在进入生产之前请求正确的批准。
对于生产数据库,目标不应是尽可能快地做出更改,而是让更改可靠、透明且充满信心。
本指南是我们在 Snowflake DCM 项目的 Infrastructure as Code 两部分系列中的最终指南
后续步骤
- 在 docs.snowflake.com
- 注册一个 Snowflake 试用版
- 注册一个 GitHub 账户
如果你觉得这有用,请在 LinkedIn 上关注我,以获取更多数据工程和 Snowflake AI Data Cloud 用例。
Snowflake DCM 项目设置指南:DCM GitHub CI/CD 管道 最初发布于 Snowflake Builders Blog: Data Engineers, App Developers, AI, & Data Science(位于 Medium 上),人们在那里通过突出并回应这个故事来继续对话。
这篇内容对你有用吗?
反馈只用于改善内容筛选,不等同于收藏