Geleneksel bir CI/CD kurulumunda SQL Server Database Project’leriyle çalıştıysanız, “Şu an hangi ortama deploy ediyorum?” sorununu muhtemelen SQLCMD değişkenleriyle çözmüşsünüzdür. Bir $(Environment) değişkeni tanımlar, ayrı publish profillerinde bunu DEV, TEST ya da PROD olarak ayarlar ve post-deployment script’inde bu değere göre dallanırsınız. Basit ve güvenilir.
Sonra Microsoft Fabric’teki SQL database’e geçersiniz ve bu yöntem artık işe yaramaz.
Sorun
Fabric SQL database, yerleşik Git entegrasyonu ve deployment pipeline’larıyla birlikte gelir. Arka planda hâlâ bir SQL projesi (.sqlproj) kullanılır, ancak bu dosyanın sahibi Fabric’tir. Depodaki .sqlproj dosyasına yaptığınız manuel değişiklikler, Fabric bir sonraki kez source control’e commit ettiğinde sıfırlanır. Düzenleyebileceğiniz bir publish profile da yoktur, çünkü sqlpackage‘ı siz çalıştırmazsınız. Deploy işlemini Fabric sizin yerinize yapar.
Bu da şu anlama gelir: Özel SQLCMD değişkenleri yok ve script’lerinize hangi ortamda çalıştıklarını söylemenin kolay bir yolu yok.
İyi haber şu ki Fabric artık yerleşik CI/CD yeteneklerinin bir parçası olarak pre- ve post-deployment script’lerini destekliyor. Shared Queries altında bir sorgu oluşturup menüsünü açıyor ve Set as Post-deployment Script seçeneğini seçiyorsunuz. Bundan sonra veritabanı Git’ten güncellendiğinde ya da bir deployment pipeline üzerinden deploy edildiğinde bu sorgu otomatik olarak çalışıyor.
Yani her deploy’da çalışan bir kancamız var. Eksik olan, bu script’in nerede çalıştığını anlamasının bir yolu.
Veritabanına nerede yaşadığını sormak
Fabric’te her ortam genellikle kendi workspace’inde bulunur: biri dev, biri test, biri prod için. Veritabanı bize hangi workspace’e ait olduğunu söyleyebilirse, buna göre dallanabiliriz.
Ve gerçekten de söyleyebiliyor. Bir Fabric SQL database’de SERVERPROPERTY('ServerName') ne döndürüyor, bakalım:
sql
SELECT SERVERPROPERTY('ServerName') AS ServerName;
Sonuç şuna benzer:
3f7a1c92-5b4e-4d8a-9c21-7e6f0b8d4a15-a91d4e27-0c6b-4f3e-8b75-2d9c1e6f8a03.database.fabric.com
Sunucu adı, bir tireyle birleştirilmiş iki GUID’den ve ardından gelen .database.fabric.com sonekinden oluşur:
<tenant-id>-<workspace-id>.database.fabric.com
3f7a1c92-5b4e-4d8a-9c21-7e6f0b8d4a15 - a91d4e27-0c6b-4f3e-8b75-2d9c1e6f8a03 .database.fabric.com
└──────────── Tenant ID ─────────────┘ └─────────── Workspace ID ────────────┘
İlk GUID, Microsoft Entra tenant ID’nizdir. Kuruluşunuzdaki tüm veritabanları için aynıdır, dolayısıyla ortamları birbirinden ayırmakta işe yaramaz. İkinci GUID ise veritabanının bulunduğu Fabric workspace’inin ID’sidir ve tam olarak aradığımız ortam parmak izi budur.
İpucu: Hangi workspace ID’nin hangi ortama ait olduğunu öğrenmek için her workspace’i Fabric portalında açıp adres çubuğuna bakın: app.fabric.microsoft.com/groups/<workspace-id>/.... Bu, sunucu adında gördüğünüz GUID’in ta kendisidir.
Workspace ID’yi ayıklamak
Sunucu adının tamamını karşılaştırmak yerine workspace ID’yi ayıklamak daha doğrudur. Her GUID 36 karakter uzunluğundadır. Yani tenant ID 1 ile 36 arasındaki konumları kaplar, workspace ID ise aradaki tireden sonra 38. konumdan başlar:
sql
DECLARE @server NVARCHAR(256) = CAST(SERVERPROPERTY('ServerName') AS NVARCHAR(256));
SELECT
LEFT(@server, 36) AS TenantId,
SUBSTRING(@server, 38, 36) AS WorkspaceId;
Post-deployment script’inde dallanmak
Artık workspace’e göre farklı davranan bir post-deployment script’i yazabilirsiniz:
sql
DECLARE @workspaceId CHAR(36) =
SUBSTRING(CAST(SERVERPROPERTY('ServerName') AS NVARCHAR(256)), 38, 36);
IF @workspaceId = 'a91d4e27-0c6b-4f3e-8b75-2d9c1e6f8a03'
BEGIN
PRINT 'Production workspace detected';
-- Yalnızca production'a özel mantık
END
ELSE IF @workspaceId = '5c2e8b14-9f7a-4d61-a3c8-0e4b7d2f9a6c'
BEGIN
PRINT 'Test workspace detected';
-- Test verisi yükleme, tanılamayı etkinleştirme vb.
END
ELSE
BEGIN
PRINT 'Development or unknown workspace';
-- Güvenli varsayılan davranış
END
ELSE koluna dikkat edin. Birazdan göreceğimiz gibi, göründüğünden çok daha önemli.
Dikkat edilmesi gerekenler
Workspace ID’ler kalıcı değildir. Bir workspace silinip yeniden oluşturulursa yeni bir ID alır ve script’iniz sessizce ELSE koluna düşer. Workspace’leri yeniden yapılandırırken bunu aklınızda tutun.
Branch-out yeni workspace’ler oluşturur. Fabric’in “branch out to a new workspace” özelliği her feature branch’e kendi ID’si olan ayrı bir workspace verir. Bunları önceden listeleyemezsiniz, bu yüzden yedek kolun güvenli davrandığından emin olun. Bilinmeyen workspace’leri geliştirme ortamı gibi ele almak genellikle doğru tercihtir. Bilinmeyen bir workspace asla production davranışına düşmemeli.
GUID’lerin tamamını karşılaştırın. LIKE '%a91d4e27%' yazmak cazip gelebilir, ama kısmi eşleştirme sinsi hatalara davetiye çıkarır. Workspace ID’yi tam olarak ayıklayın ve eşitlikle karşılaştırın.
Bu yöntem sunucu adının formatına bağlıdır. Microsoft bu formatı bağlayıcı bir arayüz olarak belgelemiyor, yani ileride değişebilir. Ayrıştırma mantığını tek bir yerde tutun ki gerekirse kolayca düzeltebilesiniz.
Daha dayanıklı bir alternatif: konfigürasyon tablosu
Workspace ID’leri koda gömmek size kırılgan geliyorsa, Fabric’in deploy modelinin işe yarar bir özelliğinden yararlanabilirsiniz: Şemayı günceller ama mevcut veriyi olduğu gibi bırakır.
Projenizde, şeması sürüm kontrolünde olacak şekilde bir konfigürasyon tablosu tanımlayın:
sql
CREATE TABLE dbo.EnvironmentConfig (
ConfigKey NVARCHAR(50) NOT NULL PRIMARY KEY,
ConfigValue NVARCHAR(200) NOT NULL
);
Ardından her workspace’te bir kez ve elle ortam değerini ekleyin:
sql
INSERT INTO dbo.EnvironmentConfig (ConfigKey, ConfigValue)
VALUES ('Environment', 'PROD');
Bu satır yalnızca o veritabanında yaşar. Git’te yer almaz ve deploy’lar ona dokunmaz. Önemli bir kural: Bu INSERT‘ü post-deployment script’inize koymayın. Script her yerde aynı şekilde çalıştığı için ortama özel değerlerinizin üzerine yazar.
İki yaklaşımı birleştirmek
İkisini birlikte de kullanabilirsiniz: Önce konfigürasyon tablosundan okuyun, tablo boşsa workspace ID’ye düşün. Bu sayede henüz yapılandırılmamış, yeni dallanmış workspace’ler de ele alınmış olur:
sql
DECLARE @env NVARCHAR(200) =
(SELECT ConfigValue FROM dbo.EnvironmentConfig WHERE ConfigKey = 'Environment');
IF @env IS NULL
BEGIN
DECLARE @workspaceId CHAR(36) =
SUBSTRING(CAST(SERVERPROPERTY('ServerName') AS NVARCHAR(256)), 38, 36);
SET @env = CASE @workspaceId
WHEN 'a91d4e27-0c6b-4f3e-8b75-2d9c1e6f8a03' THEN 'PROD'
WHEN '5c2e8b14-9f7a-4d61-a3c8-0e4b7d2f9a6c' THEN 'TEST'
WHEN 'e8b3f607-1d4c-4a92-b5e7-6c0a9f3d2b81' THEN 'DEV'
ELSE 'DEV'
END;
END
PRINT CONCAT('Deploying to: ', @env);
Sonuç
Fabric’in yönetilen Git entegrasyonu SQLCMD değişkenlerini elinizden alıyor, ama ortama duyarlı deploy’lar yazma imkânını almıyor. Her Fabric SQL database’in sunucu adı <tenant-id>-<workspace-id>.database.fabric.com kalıbını izler ve bu da script’lerinize hangi workspace’te çalıştıklarını anlamaları için güvenilir bir yol sunar. Buna, konfigürasyon tablosunu uygulanabilir kılan, veriyi koruyan Fabric deploy’larını da eklediğinizde elinizde iki sağlam yapı taşı olur. İş akışınıza uyanı seçin ya da ikisini birleştirin, ve bilinmeyen ortamların her zaman güvenli bir davranışa düştüğünden emin olun.