能否为部署到Azure的应用和数据库创建统一的DevOps CI/CD流水线?
实现结论
完全可以实现,核心思路是将流水线拆分为顺序执行的独立阶段,前序阶段执行失败自动终止后续流程,刚好匹配先部署数据库构件、再部署应用的要求。
前置准备
先统一管理所有数据库变更资源,避免零散存储:
- 所有表结构修改、存储过程/函数增改的SQL脚本按版本号命名,例如
V1.0.0__init_base_tables.sql、V1.0.1__add_order_query_procedure.sql,统一存放到项目根目录下的/db/migrations文件夹中 - 生产、测试环境的数据库连接字符串以加密变量形式存储在流水线的密钥管理模块,禁止硬编码到脚本或配置文件中
具体操作步骤
你可以根据现有技术栈二选一:
方案1:不引入额外工具,用原生脚本实现
无需修改现有ADO.NET业务代码,直接在流水线中添加数据库部署阶段即可:
- 在流水线配置中新增第一个阶段,命名为
DatabaseDeploy,执行逻辑如下:# 按版本号顺序执行所有未部署的SQL脚本 $dbConnString = "$(你的加密数据库连接串变量)" $sqlPath = "./db/migrations" $conn = New-Object System.Data.SqlClient.SqlConnection($dbConnString) $conn.Open() # 先检查是否存在变更记录表,没有就新建(用来记录已经执行过的脚本,避免重复执行) $checkTableCmd = New-Object System.Data.SqlClient.SqlCommand("IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'DbMigrationHistory') CREATE TABLE DbMigrationHistory (ScriptName NVARCHAR(255) PRIMARY KEY, ExecuteTime DATETIME DEFAULT GETDATE())", $conn) $checkTableCmd.ExecuteNonQuery() # 按文件名升序遍历所有SQL脚本 Get-ChildItem $sqlPath -Filter "*.sql" | Sort-Object Name | ForEach-Object { $scriptName = $_.Name # 检查脚本是否已经执行过 $checkScriptCmd = New-Object System.Data.SqlClient.SqlCommand("SELECT COUNT(1) FROM DbMigrationHistory WHERE ScriptName = @ScriptName", $conn) $checkScriptCmd.Parameters.AddWithValue("@ScriptName", $scriptName) | Out-Null $executed = $checkScriptCmd.ExecuteScalar() if ($executed -eq 0) { # 执行未部署的脚本 $sqlContent = Get-Content $_.FullName -Raw $execCmd = New-Object System.Data.SqlClient.SqlCommand($sqlContent, $conn) $execCmd.ExecuteNonQuery() # 记录执行历史 $recordCmd = New-Object System.Data.SqlClient.SqlCommand("INSERT INTO DbMigrationHistory (ScriptName) VALUES (@ScriptName)", $conn) $recordCmd.Parameters.AddWithValue("@ScriptName", $scriptName) | Out-Null $recordCmd.ExecuteNonQuery() } } $conn.Close() - 新增第二个阶段
AppDeploy,配置为依赖DatabaseDeploy阶段执行成功后触发,正常执行ASP.NET Core MVC应用的构建、打包、发布流程即可。
方案2:用EF Core迁移工具管理(适配成本极低)
如果你愿意引入轻量工具,无需修改现有ADO.NET业务代码,就可以实现更规范的变更管理:
- 新建一个独立的类库项目,只用来管理数据库迁移,引入EF Core SqlServer包
- 每次需要修改数据库时,创建对应的迁移文件,原生SQL语句可以通过
migrationBuilder.Sql("你的SQL语句")嵌入迁移逻辑 - 流水线第一阶段执行
dotnet ef database update --connection "$(加密数据库连接串)"命令,自动按顺序执行所有未部署的变更 - 第一阶段执行成功后,再正常执行应用部署流程即可
部署顺序自定义方法
如果后续需要调整部署顺序,直接调整流水线配置中阶段的排列顺序即可,也可以根据需求添加手动审批节点,例如数据库部署完成后需要DBA审批通过再执行应用部署。
内容的提问来源于stack exchange,提问作者money fresher
相关产品推荐
相关产品推荐

