<p>Bonjour,</p>
<p>La gestion des coûts d’une base de données <strong>Azure SQL Database</strong> est une préoccupation légitime, surtout pour les environnements de développement, de test ou les applications avec des plages d’inactivité prévisibles. La bonne nouvelle : Azure propose plusieurs mécanismes natifs pour réduire, voire éliminer les coûts pendant les périodes d’inactivité. Je vais vous présenter toutes les options disponibles avec leurs avantages, limites et implémentations concrètes.</p>
<h2><a name="p-34579-comprendre-la-facturation-dazure-sql-database-1" class="anchor" href="#p-34579-comprendre-la-facturation-dazure-sql-database-1" aria-label="Heading link"></a>Comprendre la facturation d’Azure SQL Database</h2>
<h3><a name="p-34579-modles-de-tarification-2" class="anchor" href="#p-34579-modles-de-tarification-2" aria-label="Heading link"></a>Modèles de tarification</h3>
<p>Avant de choisir une stratégie d’arrêt, il est essentiel de comprendre comment vous êtes facturé :</p>
<div class="md-table">
<table>
<thead>
<tr>
<th>Modèle</th>
<th>Description</th>
<th>Peut être “arrêté” ?</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>DTU (Database Transaction Unit)</strong></td>
<td>Modèle groupé CPU/RAM/IO</td>
<td>Non natif</td>
</tr>
<tr>
<td><strong>vCore Provisionné</strong></td>
<td>Ressources dédiées configurables</td>
<td>Oui (pause/resume)</td>
</tr>
<tr>
<td><strong>Serverless</strong></td>
<td>Mise à l’échelle automatique + pause automatique</td>
<td>Oui (automatique)</td>
</tr>
<tr>
<td><strong>Hyperscale</strong></td>
<td>Pour très grands volumes de données</td>
<td>Non</td>
</tr>
<tr>
<td><strong>Elastic Pool</strong></td>
<td>Ressources partagées entre plusieurs BDD</td>
<td>Partiellement</td>
</tr>
</tbody>
</table>
</div><h2><a name="p-34579-solution-1-azure-sql-database-serverless-recommande-3" class="anchor" href="#p-34579-solution-1-azure-sql-database-serverless-recommande-3" aria-label="Heading link"></a>Solution 1 : Azure SQL Database Serverless (recommandée)</h2>
<p>La solution la plus élégante et la plus simple est de migrer vers le <strong>niveau Serverless</strong>. C’est la réponse native d’Azure à votre besoin.</p>
<h3><a name="p-34579-fonctionnement-du-niveau-serverless-4" class="anchor" href="#p-34579-fonctionnement-du-niveau-serverless-4" aria-label="Heading link"></a>Fonctionnement du niveau Serverless</h3>
<p>Le niveau Serverless offre deux caractéristiques clés :</p>
<ul>
<li><strong>Mise à l’échelle automatique</strong> : ajuste le nombre de vCores selon la charge (entre un min et un max configurables)</li>
<li><strong>Pause automatique</strong> : suspend la base de données après une période d’inactivité configurable (minimum 1 heure)</li>
</ul>
<p><strong>Facturation :</strong> vous ne payez que pour le <strong>stockage</strong> pendant les périodes de pause, et pour les <strong>vCores effectivement utilisés</strong> pendant l’activité.</p>
<h3><a name="p-34579-configuration-via-azure-cli-5" class="anchor" href="#p-34579-configuration-via-azure-cli-5" aria-label="Heading link"></a>Configuration via Azure CLI</h3>
<pre data-code-wrap="bash"><code class="lang-bash"># Créer une base de données Serverless
az sql db create \
--resource-group MonResourceGroup \
--server mon-serveur-sql \
--name MaBDD \
--edition GeneralPurpose \
--family Gen5 \
--capacity 2 \
--compute-model Serverless \
--auto-pause-delay 60 \
--min-capacity 0.5
Modifier une BDD existante vers Serverless
az sql db update \
--resource-group MonResourceGroup \
--server mon-serveur-sql \
--name MaBDD \
--edition GeneralPurpose \
--family Gen5 \
--capacity 2 \
--compute-model Serverless \
--auto-pause-delay 120 \
--min-capacity 0.5
</code></pre>
<h3><a name="p-34579-configuration-via-powershell-6" class="anchor" href="#p-34579-configuration-via-powershell-6" aria-label="Heading link"></a>Configuration via PowerShell</h3>
<pre data-code-wrap="powershell"><code class="lang-powershell"># Modifier une base de données existante vers Serverless
Set-AzSqlDatabase -ResourceGroupName "MonResourceGroup"
-ServerName "mon-serveur-sql" -DatabaseName "MaBDD"
-Edition "GeneralPurpose" -ComputeModel "Serverless"
-ComputeGeneration "Gen5" -MinVcore 0.5
-MaxVcore 2 `
-AutoPauseDelayInMinutes 60
</code></pre>
<h3><a name="p-34579-considrations-importantes-sur-serverless-7" class="anchor" href="#p-34579-considrations-importantes-sur-serverless-7" aria-label="Heading link"></a>Considérations importantes sur Serverless</h3>
<ul>
<li><strong>Latence au réveil (“cold start”)</strong> : La première connexion après une pause peut prendre <strong>20 à 30 secondes</strong> le temps que la base se réveille. À gérer côté application avec une logique de retry.</li>
<li><strong>Non compatible avec</strong> : les Elastic Pools, les instances managées, Hyperscale</li>
<li><strong>Disponible uniquement</strong> en tier <strong>General Purpose</strong> avec vCores Gen5</li>
</ul>
<h2><a name="p-34579-solution-2-pauseresume-manuelle-vcore-provisionn-8" class="anchor" href="#p-34579-solution-2-pauseresume-manuelle-vcore-provisionn-8" aria-label="Heading link"></a>Solution 2 : Pause/Resume manuelle (vCore Provisionné)</h2>
<p>Pour les bases de données <strong>vCore Provisionnées</strong>, vous pouvez mettre en pause et reprendre manuellement la base de données.</p>
<blockquote>
<p><strong>Note :</strong> Cette fonctionnalité est disponible sur le niveau <strong>General Purpose</strong> et certains tiers premium. Vérifiez la disponibilité pour votre configuration.</p>
</blockquote>
<h3><a name="p-34579-via-azure-cli-9" class="anchor" href="#p-34579-via-azure-cli-9" aria-label="Heading link"></a>Via Azure CLI</h3>
<pre data-code-wrap="bash"><code class="lang-bash"># Mettre en pause une base de données
az sql db update \
--resource-group MonResourceGroup \
--server mon-serveur-sql \
--name MaBDD \
--status Paused
Reprendre une base de données
az sql db update \
--resource-group MonResourceGroup \
--server mon-serveur-sql \
--name MaBDD \
--status Online
</code></pre>
<h3><a name="p-34579-via-azure-powershell-10" class="anchor" href="#p-34579-via-azure-powershell-10" aria-label="Heading link"></a>Via Azure PowerShell</h3>
<pre data-code-wrap="powershell"><code class="lang-powershell"># Mettre en pause
Suspend-AzSqlDatabase -ResourceGroupName "MonResourceGroup"
-ServerName "mon-serveur-sql" `
-DatabaseName "MaBDD"
Reprendre
Resume-AzSqlDatabase -ResourceGroupName "MonResourceGroup"
-ServerName "mon-serveur-sql" `
-DatabaseName "MaBDD"
</code></pre>
<h2><a name="p-34579-solution-3-automatisation-avec-azure-automation-ou-logic-apps-11" class="anchor" href="#p-34579-solution-3-automatisation-avec-azure-automation-ou-logic-apps-11" aria-label="Heading link"></a>Solution 3 : Automatisation avec Azure Automation ou Logic Apps</h2>
<p>Pour arrêter et démarrer automatiquement selon un planning, plusieurs options s’offrent à vous.</p>
<h3><a name="p-34579-option-a-azure-automation-avec-runbook-powershell-12" class="anchor" href="#p-34579-option-a-azure-automation-avec-runbook-powershell-12" aria-label="Heading link"></a>Option A : Azure Automation avec Runbook PowerShell</h3>
<pre data-code-wrap="powershell"><code class="lang-powershell"># Runbook PowerShell pour pause/resume planifié
param(
[Parameter(Mandatory=$true)]
[string]$Action, # "Pause" ou "Resume"
[string]$ResourceGroupName = "MonResourceGroup",
[string]$ServerName = "mon-serveur-sql",
[string]$DatabaseName = "MaBDD"
)
Authentification via Managed Identity
Connect-AzAccount -Identity
switch ($Action) {
"Pause" {
Write-Output "Mise en pause de $DatabaseName..."
Suspend-AzSqlDatabase -ResourceGroupName $ResourceGroupName
-ServerName $ServerName -DatabaseName $DatabaseName
Write-Output "Base de données mise en pause avec succès."
}
"Resume" {
Write-Output "Reprise de $DatabaseName..."
Resume-AzSqlDatabase
-ResourceGroupName $ResourceGroupName -ServerName $ServerName
-DatabaseName $DatabaseName
Write-Output "Base de données reprise avec succès."
}
}
</code></pre>
<p>Configurez ensuite deux <strong>planifications (Schedules)</strong> dans Azure Automation :</p>
<ul>
<li>Pause : tous les jours à 20h00</li>
<li>Resume : tous les jours à 7h00</li>
</ul>
<h3><a name="p-34579-option-b-azure-logic-apps-avec-planificateur-13" class="anchor" href="#p-34579-option-b-azure-logic-apps-avec-planificateur-13" aria-label="Heading link"></a>Option B : Azure Logic Apps avec planificateur</h3>
<ol>
<li>Créez une <strong>Logic App</strong> avec un déclencheur <strong>Recurrence</strong></li>
<li>Ajoutez une action <strong>HTTP</strong> ou utilisez le connecteur <strong>Azure SQL</strong></li>
<li>Appelez l’API REST Azure pour pauseer/reprendre :</li>
</ol>
<pre><code class="lang-auto">PUT https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Sql/servers/{serverName}/databases/{databaseName}?api-version=2021-11-01
Body: { "properties": { "status": "Paused" } }
</code></pre>
<h3><a name="p-34579-option-c-script-powershell-via-azure-functions-timer-trigger-14" class="anchor" href="#p-34579-option-c-script-powershell-via-azure-functions-timer-trigger-14" aria-label="Heading link"></a>Option C : Script PowerShell via Azure Functions (Timer Trigger)</h3>
<pre data-code-wrap="powershell"><code class="lang-powershell"># function.json
{
"bindings": [
{
"name": "myTimer",
"type": "timerTrigger",
"direction": "in",
"schedule": "0 0 20 * * 1-5" // Lundi-vendredi à 20h
}
]
}
</code></pre>
<h2><a name="p-34579-solution-4-azure-sql-managed-instance-arrt-planifi-15" class="anchor" href="#p-34579-solution-4-azure-sql-managed-instance-arrt-planifi-15" aria-label="Heading link"></a>Solution 4 : Azure SQL Managed Instance (arrêt planifié)</h2>
<p>Depuis 2023, <strong>Azure SQL Managed Instance</strong> supporte également l’arrêt et le démarrage planifiés :</p>
<pre data-code-wrap="bash"><code class="lang-bash"># Arrêter une Managed Instance
az sql mi stop --resource-group MonResourceGroup --name MonInstance
Démarrer une Managed Instance
az sql mi start --resource-group MonResourceGroup --name MonInstance
Configurer un planning d'arrêt automatique
az sql mi update \
--resource-group MonResourceGroup \
--name MonInstance \
--instance-pool-name "" \
--timezone-id "Romance Standard Time"
</code></pre>
<h2><a name="p-34579-comparaison-des-stratgies-dconomie-16" class="anchor" href="#p-34579-comparaison-des-stratgies-dconomie-16" aria-label="Heading link"></a>Comparaison des stratégies d’économie</h2>
<div class="md-table">
<table>
<thead>
<tr>
<th>Stratégie</th>
<th>Économies potentielles</th>
<th>Complexité</th>
<th>Cold Start</th>
<th>Cas d’usage idéal</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Serverless</strong></td>
<td>60-90%</td>
<td>Faible</td>
<td>20-30s</td>
<td>Dev/Test, charge variable</td>
</tr>
<tr>
<td><strong>Pause manuelle</strong></td>
<td>100% compute</td>
<td>Faible</td>
<td>2 min</td>
<td>Hors heures de bureau</td>
</tr>
<tr>
<td><strong>Automation planifiée</strong></td>
<td>50-80%</td>
<td>Moyenne</td>
<td>2 min</td>
<td>Planning fixe connu</td>
</tr>
<tr>
<td><strong>Elastic Pool</strong></td>
<td>Variable</td>
<td>Moyenne</td>
<td>Aucun</td>
<td>Plusieurs BDD similaires</td>
</tr>
<tr>
<td><strong>Basic/Free tier</strong></td>
<td>Coût fixe bas</td>
<td>Faible</td>
<td>Aucun</td>
<td>Très petites BDD</td>
</tr>
</tbody>
</table>
</div><h2><a name="p-34579-surveillance-et-optimisation-des-cots-17" class="anchor" href="#p-34579-surveillance-et-optimisation-des-cots-17" aria-label="Heading link"></a>Surveillance et optimisation des coûts</h2>
<h3><a name="p-34579-alertes-de-cot-via-azure-cost-management-18" class="anchor" href="#p-34579-alertes-de-cot-via-azure-cost-management-18" aria-label="Heading link"></a>Alertes de coût via Azure Cost Management</h3>
<pre data-code-wrap="bash"><code class="lang-bash"># Créer une alerte de budget pour la base de données
az consumption budget create \
--budget-name "BudgetSQLDatabase" \
--amount 50 \
--time-grain Monthly \
--start-date 2024-01-01 \
--end-date 2025-01-01 \
--resource-group MonResourceGroup \
--notifications '[{"enabled":true,"operator":"GreaterThan","threshold":80,"contactEmails":["admin@monentreprise.com"],"thresholdType":"Actual"}]'
</code></pre>
<h3><a name="p-34579-mtriques-surveiller-19" class="anchor" href="#p-34579-mtriques-surveiller-19" aria-label="Heading link"></a>Métriques à surveiller</h3>
<pre data-code-wrap="bash"><code class="lang-bash"># Vérifier les métriques de la base de données
az monitor metrics list \
--resource "/subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Sql/servers/{server}/databases/{db}" \
--metric "cpu_percent,dtu_consumption_percent,storage" \
--interval PT1H
</code></pre>
<hr>
<p>En résumé, la solution <strong>Serverless avec pause automatique</strong> est la plus adaptée pour la majorité des cas d’utilisation car elle automatise complètement la gestion sans intervention manuelle. Si vous avez un planning d’utilisation fixe et prévisible, combinez la pause manuelle avec <strong>Azure Automation</strong> pour des économies maximales.</p>
<p>Pouvez-vous préciser votre cas d’usage (développement, production, planning d’utilisation) ? Je pourrai ainsi vous recommander la configuration optimale et vous aider à estimer les économies réalisables.</p>