Skip to main content

Database Deployment Automation β€” ARM, Bicep, PowerShell & CLI

Automating database deployment ensures consistency, repeatability, and auditability. No manual portal clicks in production β€” everything as code.

Infrastructure as Code (IaC) Options​

ToolTypeBest ForLearning Curve
ARM TemplatesJSON declarativeLegacy deployments, complex dependenciesHigh
BicepDSL (compiles to ARM)All new Azure deploymentsLow-Medium
TerraformHCL declarativeMulti-cloud, team standardizationMedium
PowerShell (Az module)Imperative scriptingQuick tasks, automation runbooksLow
Azure CLIImperative CLIBash-friendly, CI/CD pipelinesLow
🎯 Exam Focus

DP-300 focus: You need to understand ARM/Bicep for declarative deployments, and PowerShell/CLI for imperative operations. Know the difference: declarative = "this is what I want" (ARM/Bicep/Terraform), imperative = "do this step by step" (PowerShell/CLI).

ARM Templates vs Bicep​

AspectARM TemplateBicep
FormatJSONDSL (cleaner syntax)
ReadabilityVerbose, nestedClean, concise
ModulesNested templatesNative module support
ParametersJSON param files.bicepparam files
IntellisenseLimitedFull VS Code support
OutputJSON ARM templateCompiles to ARM JSON
Microsoft recommendationLegacyβœ… Recommended
🏒 Real-World DBA Note

Always use Bicep for new deployments. ARM JSON templates are still supported but Bicep is Microsoft's recommended approach. Bicep files are 60-80% shorter than equivalent ARM JSON and have full VS Code IntelliSense.

What Can You Deploy?​

ResourceBicep/ARMPowerShell/CLI
Logical SQL Serverβœ…βœ…
Azure SQL Databaseβœ…βœ…
Elastic Poolβœ…βœ…
Managed Instanceβœ…βœ…
Failover Groupβœ…βœ…
Firewall Rulesβœ…βœ…
Private Endpointβœ…βœ…
SQL VM (IaaS)βœ…βœ…
VNet + NSGβœ…βœ…
Auditing + ATPβœ…βœ…

Deployment Patterns​

Pattern 1: Full Environment (Bicep)​

Deploy a complete environment in one command:

  • VNet + Subnet + NSG
  • Logical SQL Server + Databases
  • Firewall rules + Private Endpoint
  • Auditing β†’ Log Analytics
  • Failover Group (cross-region)

This is the recommended production pattern β€” everything defined in code, version-controlled, repeatable.

Pattern 2: Database-Level Changes (PowerShell/CLI)​

Day-to-day operations after initial deployment:

  • Scale vCores up/down
  • Change backup retention
  • Add/remove databases from elastic pool
  • Configure auto-tuning
  • Manage firewall rules

Pattern 3: CI/CD Pipeline (Azure DevOps / GitHub Actions)​

Automated deployment on every code push:

  1. Developer commits Bicep/SQL script to Git
  2. Pipeline validates (what-if / plan)
  3. Approval gate for production
  4. Deploy infrastructure changes
  5. Deploy schema changes (DACPAC/SSDT)

Schema Deployment Tools​

ToolWhat It DoesBest For
SSDT (SQL Server Data Tools)Visual Studio project for database schemaSchema version control, diff-based deploy
DACPACCompiled schema packageCI/CD pipeline schema deployment
SqlPackage.exeCLI tool to deploy DACPACsAutomation, cross-platform
dbup / Flyway / LiquibaseMigration-based schema changesIncremental migration scripts
EF Core MigrationsORM-based schema management.NET application teams
🎯 Exam Focus

DACPAC (Data-tier Application Package) is a key DP-300 concept. It contains a database schema definition and can be used to deploy schema changes or extract/import database structures. SqlPackage.exe is the CLI tool for DACPAC operations.

Azure DevOps Pipeline for SQL​

A typical pipeline:

StageWhat Happens
BuildCompile SSDT project β†’ produce DACPAC
ValidateRun what-if against target DB (dry run)
Deploy to DevAuto-deploy DACPAC to dev environment
TestRun integration tests against dev DB
Deploy to StagingDeploy to staging with approval gate
Deploy to ProdManual approval β†’ deploy to production

Key Deployment Concepts​

Idempotency​

Declarative deployments (Bicep/ARM) are idempotent β€” running the same template twice produces the same result without errors. This is critical for reliable automation.

What-If / Preview​

Always preview changes before deploying:

  • Bicep/ARM: az deployment group what-if
  • Terraform: terraform plan
  • DACPAC: SqlPackage /Action:DeployReport

State Management​

ToolState
ARM/BicepAzure manages state (resource-level)
Terraform.tfstate file (you manage β€” use remote backend)
PowerShell/CLINo state (imperative = you track manually)
⚠️ Watch Out

Never deploy infrastructure changes from a developer's laptop to production. Always use a CI/CD pipeline with approval gates, audit logging, and rollback capability. Treat database deployments with the same rigor as application deployments.


Anti-Patterns​

  • "Deploy infra and schema in the same pipeline stage." Couples infra failures to schema rollbacks. Separate stages: infra (Bicep) β†’ schema (DACPAC / migrations) β†’ app (release).
  • "DACPAC β€˜Drop objects not in source’ enabled in prod." Will silently delete tables that have data but aren't in the project. Disable in prod publish profiles; allow only in dev/test.
  • "Run schema migrations from the deploying user's account." Should run as a scoped pipeline identity with db_ddladmin only. Don't reuse the dev's account.
  • "Roll back schema by re-running an old DACPAC." Schema is one-way for many changes (dropped columns can't be recovered without backup). Always backup before deploy and test rollback.
  • "Single Bicep file = whole production." Monolithic templates hit the deployment depth/size limits. Break into modules + subscription-scope deployments.
  • "Trust --no-prompt on every change." DACPAC and azd flags that suppress prompts also suppress useful warnings. Read the pre-deploy report before merging the PR.
⚠️ Watch Out

azd up runs azd provision + azd deploy β€” it provisions infra AND publishes app code. For infra-only changes use azd provision. For app-only deploys use azd deploy. Mixing them in CI without intent re-deploys both unnecessarily.


Migration Between Deployment Pipelines​

From β†’ ToPathCost
Manual portal deploy β†’ GitHub ActionsWire OIDC + what-if on PROne-time setup; gains audit trail
Imperative scripts β†’ Bicep + modulesRefactor; adopt AVM where possibleDeclarative; smaller diff per change
Bicep β†’ TerraformRewrite in HCL; migrate stateMulti-cloud option; state file mgmt
Hand-written pipelines β†’ azd templateAdopt azd init + azure.yamlLower boilerplate; opinionated
Schema in app pipeline β†’ separate schema pipelineSplit DACPAC stage; gate behind approvalClearer ownership; longer release window
DACPAC β†’ EF Core migrationsAdopt EF migrations; deprecate DACPACCode-driven; less schema drift
Direct prod deploy β†’ ring deployment (canary)Stage β†’ 5 % β†’ 50 % β†’ 100 %Catches regressions early; pipeline complexity
Push deploy β†’ GitOps (Flux/Argo)Reconciler watches repo β†’ clusterSelf-healing; setup cost

Most expensive moves: DACPAC β†’ EF migrations (schema philosophy change) and Bicep β†’ Terraform (HCL rewrite + state).


Real Scenarios​

  1. Greenfield SaaS, single team β†’ azd template + Bicep + GitHub Actions + DACPAC for schema. Driver: lowest scaffold time. Trade-off: opinionated structure.
  2. Enterprise with platform team β†’ product teams β†’ Platform team owns Bicep modules in private registry; product teams consume via br: references. Driver: standardization + autonomy. Trade-off: registry maintenance.
  3. Multi-region SQL DB schema change β†’ Pipeline runs DACPAC on primary; FOG replicates to secondary. Driver: avoid divergence. Trade-off: replication lag visible during deploy.
  4. Compliance: every change auditable β†’ Branch protection + reviewer required + signed commits + Bicep what-if artifact stored in pipeline. Driver: regulator evidence. Trade-off: PR cycle time.
  5. High-velocity dev, low-blast-radius env β†’ PR β†’ ephemeral environment via azd up β†’ auto-delete after merge. Driver: testing in isolation. Trade-off: cost per PR (mitigate with TTL).

Flashcards​

What is the difference between declarative and imperative deployment?
Click to reveal answer
Declarative (Bicep/ARM/Terraform): 'This is what I want' β€” the tool figures out how. Imperative (PowerShell/CLI): 'Do this step by step' β€” you control the sequence.
1 / 5

Quiz​

Q1/5
0 correct
Your team needs to deploy identical Azure SQL environments for dev, staging, and production. What approach should you use?