使用SQL Database Projects與GitHub Actions打造Azure SQL資料庫CI/CD流水線

作者:楊先民
精誠資訊/恆逸教育訓練中心資深講師
※網路引用請註明完整出處
前言
在傳統的資料庫維護模式中,開發團隊通常依賴開發人員手寫 ALTER TABLE 或 CREATE PROCEDURE 等 T-SQL 變更指令碼(Migration Scripts),再由資料庫管理者(DBA)或部署人員手動對生產環境資料庫執行。
然而,手動執行的隱患極高:指令碼執行順序錯誤、環境遺漏變更、缺乏版本控制,甚至人為疏失都可能導致線上系統崩潰。為了解決這個痛點,現代化資料庫開發導入了「以狀態為基礎(State-based)」的資料庫專案模式,配合 CI/CD 流水線(Continuous Integration / Continuous Deployment),讓資料庫架構變更如同應用程式程式碼一樣,實現版本控制、自動建置驗證與無縫部署。
本文將基於 Microsoft 官方實戰教學,詳細剖析如何透過 SQL Database Projects(SDK 樣式 .sqlproj) 與 GitHub Actions,為 Azure SQL Database 打造一套現代化的 CI/CD 流程。
一、 架構核心概念:Declarative vs. Imperative
在進入操作流程前,必須先理解 SQL Database Projects 的核心哲學:宣告式(Declarative / State-based)開發。
1.
傳統變更模式(Imperative /
Migration-based): 開發者撰寫「如何變更」的步驟(如:ALTER
TABLE Add Column X),逐一按順序執行。缺點是必須精準管理每個指令碼的版控與順序。
2.
資料庫專案模式(Declarative /
State-based): 開發者只宣告「目標狀態(Desired State)」(如:專案中的
.sql 檔定義資料表最終該長什麼樣子)。當編譯專案時,會產出一個
.dacpac 檔案(Data-tier Application Package,資料層應用程式封裝檔)。部署工具(SqlPackage 或
GitHub Actions)會自動比較 .dacpac 與目標資料庫當前的架構差異,並自動生成最適切的 CREATE / ALTER / DROP 指令碼來達成一致。
二、 前置準備與環境建置
要順利執行本實驗的流水線,需要準備以下基礎設施與開發工具:
1. 雲端資源準備
· Azure SQL Database:作為部署的目標資料庫。在 Azure Portal 中建立一個資料庫(例:AdventureWorksLT),並選用 Serverless 無伺服器運算層(或開發測試層)。
· 防火牆與安全性設定:
o
在 Azure SQL Server 的防火牆設定中,將
「允許 Azure 服務和資源存取此伺服器」(Allow Azure
services and resources to access this server) 開啟為 Yes。這是為了讓 GitHub Actions 執行階段的 Runner 能夠遠端存取資料庫。
o
選擇適當的驗證方式:可選用 SQL 身份驗證(SQL Authentication,設定 Admin 帳號密碼)或 Microsoft Entra ID 驗證。
2. 本機開發環境配置
本機需安裝以下工具:
· Git 與 GitHub CLI (
gh):處理程式碼版本控制與 GitHub 資源管理。· .NET 8.0 SDK (或更新版本):提供跨平台編譯環境。
· Visual Studio Code:搭配 MSSQL Extension(內建 SQL Database Projects 支援)。
環境建置的第一步,是在本機安裝 .NET 的 SQL 專案範本:
dotnet new install Microsoft.Build.Sql.Templates
此命令會安裝 SDK 樣式的 sqlproj 範本(Microsoft.Build.Sql),讓資料庫專案可以使用跨平台的
dotnet build 命令進行編譯,不再侷限於傳統 Windows 平台的 MSBuild。
三、 建立與本機編譯 SQL
Database Project
1. 初始化資料庫專案
建立專案目錄並使用 .NET CLI 初始化 SQL 專案:
mkdir AdventureWorksDB
cd
AdventureWorksDB
dotnet new sqlproj -tp SqlAzureV12
關鍵參數說明: -tp SqlAzureV12 指定目標平台(Target Platform)為 Azure SQL Database。若未指定,預設會使用 SQL Server
本地版本,可能導致發行至 Azure 時發生功能不相容的錯誤。
初始化後會生成 AdventureWorksDB.sqlproj 檔案。SDK 樣式專案具備「預設萬用字元比對(Globbing)」特性,代表目錄下所有的 .sql 檔案都會自動被列入編譯,無須在 .sqlproj 中手動逐一清冊。
2. 加入資料庫物件 (Schema Definition)
在專案目錄下分類建立資料庫物件的 DDL 指令碼:
建立資料表檔 Tables/InventoryLog.sql:
SQL
CREATE
TABLE [dbo].[InventoryLog] (
[LogID] INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
[ProductID] INT NOT NULL,
[ChangeDate]
DATETIME2 NOT NULL DEFAULT GETDATE(),
[QuantityChange] INT NOT NULL,
[ChangeType]
NVARCHAR(20) NOT NULL
);
建立預存程序檔 StoredProcedures/uspLogInventoryChange.sql:
SQL
CREATE
PROCEDURE [dbo].[uspLogInventoryChange]
@ProductID INT,
@QuantityChange INT,
@ChangeType NVARCHAR(20)
AS
BEGIN
INSERT INTO
[dbo].[InventoryLog] (ProductID, QuantityChange, ChangeType)
VALUES (@ProductID, @QuantityChange, @ChangeType);
END;
3. 本機編譯驗證
在提交版控前,先於本機執行編譯:
dotnet build
編譯成功後,會在 bin/Debug/ 目錄下生成
AdventureWorksDB.dacpac。這個 .dacpac 包含整個資料庫模型架構,也是後續 CI/CD 流水線的核心交付物(Artifact)。
四、 版本控管與 GitHub 儲存庫綁定
完成本機建置後,透過 Git 與 GitHub CLI 將專案推送到遠端儲存庫(Repository):
初始化 Git 並進行首次提交:
git init
git add .
git commit -m "Initial commit - SQL Database Project"
使用 GitHub CLI 建立 GitHub
Repository 並推送:
gh repo create AdventureWorksDB --public --source=. --remote=origin --push
此時,資料庫專案已成功備份並託管至 GitHub。
五、 設定 GitHub Secrets 安全憑證
為了讓 GitHub Actions 自動化工作流程能夠登入並部署至
Azure SQL Database,絕對不能將密碼直接硬碼(Hardcode)在 YAML 寫死。我們必須在 GitHub 儲存庫設定敏感資訊(Secrets):
進入 GitHub Repository → Settings → Secrets and
variables → Actions,新增以下兩個 Secrets:
1.
DB_SERVER:Azure SQL Server 的完整功能變數名稱(例如:sqlserver-demo.database.windows.net)。
2.
DB_PASSWORD:Azure SQL Server 管理員帳號的密碼。
(註:若採用 Microsoft Entra ID 服務主體,則需設定 Azure Service Principal 的 Client ID、Tenant ID 與 Client Secret)。
六、 打造 GitHub Actions CI/CD 流水線
在專案根目錄下建立 .github/workflows/deploy-db.yml 檔案,定義整個 CI/CD Pipeline 的自動化流程。
一套健全的 SQL CI/CD 流水線通常分為兩個階段(Jobs):
1.Build Job(持續整合 CI):負責檢查 T-SQL 語法、編譯 .sqlproj 並生成 .dacpac 成品。
2.Deploy Job(持續部署 CD):下載
.dacpac 成品,並呼叫部署 Action 部署至 Azure SQL Database。
完整 Workflow YAML 配置範例:
YAML
name: Deploy SQL Database Project
on:
push:
branches:
- main
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
repository
uses: actions/checkout@v4
- name: Setup .NET SDK
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'
- name: Build SQL Project
run: dotnet
build AdventureWorksDB.sqlproj -c Release
- name: Upload
DACPAC Artifact
uses: actions/upload-artifact@v4
with:
name: dacpac
path: bin/Release/*.dacpac
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- name: Download
DACPAC Artifact
uses: actions/download-artifact@v4
with:
name: dacpac
- name: Deploy
DACPAC to Azure SQL Database
uses: azure/sql-action@v2.2
with:
connection-string: 'Server=tcp:${{ secrets.DB_SERVER }},1433;Initial Catalog=AdventureWorksLT;Persist Security
Info=False;User ID=sqladmin;Password=${{ secrets.DB_PASSWORD }};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection
Timeout=30;'
path: './AdventureWorksDB.dacpac'
action: 'publish'
七、 CI/CD 自動化運作與驗證測試
當我們將 .github/workflows/deploy-db.yml 提交並推送到 GitHub 的 main 分支時,GitHub
Actions 便會自動啟動!
1. 流水線執行解析
· Build 階段: Runner 會拉取最新程式碼,安裝 .NET 8 SDK,執行 dotnet build -c Release。如果 T-SQL 存在語法錯誤或引用了不存在的資料表,編譯將直接宣告失敗,達到 早期發現錯誤(Fail Fast) 的效果。成功後會將 .dacpac 暫存至 Artifact。
· Deploy 階段: deploy 工作等待 build 完成後,拉取 .dacpac,並透過官方的 azure/sql-action 連結至 Azure SQL Database。SqlPackage 引擎會精確比對目標資料庫現況,發現資料庫目前缺少 [dbo].[InventoryLog] 資料表與 [dbo].[uspLogInventoryChange] 預存程序,自動生成對應的 CREATE 敘述句並完成發行。
2. 驗證變更與持續疊代測試
為驗證 CI/CD 流水線的動態回應能力,我們可以進行二次變更測試:
1.修改架構:在本機專案的 Tables/InventoryLog.sql 資料表中加入一個新欄位,例如 [CreatedBy]
NVARCHAR(50) NULL。
2.提交程式碼:
git add .
git commit -m "Add CreatedBy column to InventoryLog"
git push origin main
1.觀察 GitHub Actions:推送後,GitHub Actions 再次觸發。InventoryLog 資料表已成功新增了 CreatedBy 欄位,且原本的資料(若有)依然完好無損!這就是 SqlPackage 在宣告式發行時自動維護資料完整性的強大之處。
八、 總結與最佳實踐建議
透過本次 Microsoft Labs 的演練,我們成功實現了資料庫架構的版控化與自動化部署。這套 SQL CI/CD 流水線帶來了以下核心優勢:
1.單一事實來源(Single Source of Truth):Git 儲存庫即為資料庫架構的權威來源,避免正式環境與開發環境架構不一致(Schema
Drift)。
2.降低部署風險:告別人工手動執行腳本,完全交由
automated pipeline 比對與發行,大大減少人為遺漏或順序錯誤的風險。
3.企業級擴充建議:
· 多環境部署(Multi-environment Support):可擴充 YAML,加入 GitHub Environments 機制。先部署至 Staging(測試環境),經由審核(Protection Rules)後再自動部署至 Production(正式環境)。
· 安全性防護:正式生產環境建議搭配 Azure
Key Vault 或 OpenID
Connect (OIDC) 進行無金鑰(Keyless)認證,進一步提升雲端資安等級。
掌握 SQL Database Projects 與 CI/CD 技術,是將現代化 Agile 與 DevOps 理念擴展至資料庫層級的必經之路。
0 意見:
張貼留言