1. はじめに
Microsoft Defender for SQL は、Azure SQL Database および Azure SQL Managed Instance に対する脆弱性評価や異常アクセス検知などを提供するセキュリティ機能です。有効化の方法はサブスクリプション単位とリソース単位の2通りあり、「どのリソースがどのレベルで保護されているか」を一元的に把握するのが意外と難しいという課題があります。
本記事では、Azure Policy カスタム定義を使って各 SQL Server・SQL Managed Instance・Synapse Analytics のリソース単位での Defender for SQL 有効化状態を継続的に監査する方法を紹介します。
Azure Storage (Defender for Storage) については、こちらのブログを参考にしてください。
なお、Azure SQL Database(Microsoft.Sql/servers)と Azure SQL Managed Instance(Microsoft.Sql/managedInstances)、Synapse Dedicated SQL Pool、Synapse Workspace(Microsoft.Synapse/workspaces)はリソース型が異なるため、それぞれ別々のポリシーが必要です。本記事で4つのカスタムポリシーを作成します。
2. Defender for SQL の有効化方式
まず、Defender for SQL の有効化方式を整理します。
| 方式 | 設定場所 | 特徴 |
|---|---|---|
| サブスクリプション単位 | Microsoft Defender for Cloud → 環境設定 → SQL | サブスク配下の全 SQL Server / SQL MI に一括適用 |
| リソース単位 | 各 SQL Server または SQL MI → Microsoft Defender for Cloud | リソース単位でオン/オフを制御 |
リソース単位で設定する場合、advancedThreatProtectionSettings リソースの state プロパティを Enabled に設定します。state には以下の3つの値があります。
| state 値 | 意味 |
|---|---|
Enabled |
リソース単位で Defender for SQL が有効 |
Disabled |
リソース単位で Defender for SQL が無効 |
New |
まだ設定されていない(デフォルト状態) |
3. 課題:Azure SQL Database と Azure SQL Managed Instance でリソース型が異なる
Defender for Storage では Microsoft.Storage/storageAccounts という単一のリソース型を対象にすればよいのに対し、Defender for SQL では以下のようにリソース型と子リソース型が完全に分かれています。
| サービス | 対象リソース型(IF 条件) | 子リソース型(existenceCondition) |
|---|---|---|
| Azure SQL Database | Microsoft.Sql/servers |
Microsoft.Sql/servers/advancedThreatProtectionSettings |
| Azure SQL Managed Instance | Microsoft.Sql/managedInstances |
Microsoft.Sql/managedInstances/advancedThreatProtectionSettings |
| Synapse Dedicated SQL Pool |
Microsoft.Sql/servers(kind に analytics を含む) |
Microsoft.Sql/servers/advancedThreatProtectionSettings |
| Synapse Workspace | Microsoft.Synapse/workspaces |
Microsoft.Synapse/workspaces/securityAlertPolicies |
Azure Policy の AuditIfNotExists は1つのポリシー定義につき1つのリソース型しか if 条件に指定できないため、4つのカスタムポリシーを作成するアプローチになります。
Microsoft.Sql/servers には Synapse Dedicated SQL Pool(kind に analytics を含む)も含まれますが、SQL DB ポリシーでは除外し、代わりに Synapse Dedicated 専用ポリシーで個別に監査します。また、Synapse Workspace は子リソース型が securityAlertPolicies(advancedThreatProtectionSettings ではない)のため別ポリシーが必要です。
4. 試してみる
4.1 ポリシー定義の作成
ポリシー 1:Azure SQL Database 用(combined-policy.json)
{
"$schema": "https://schema.management.azure.com/schemas/2019-09-01/policyDefinition.json#",
"name": "custom-defender-for-sql-db-resource-audit",
"properties": {
"displayName": "[Custom] Defender for SQL (Azure SQL Database) - Resource Level Audit",
"policyType": "Custom",
"mode": "All",
"description": "各 Azure SQL Server(Microsoft.Sql/servers)に対して、Defender for SQL がリソース単位(state: Enabled)で有効化されていることを監査します。",
"metadata": {
"version": "1.0.0",
"category": "Security Center"
},
"parameters": {
"effect": {
"type": "String",
"metadata": {
"displayName": "Effect",
"description": "AuditIfNotExists または Disabled"
},
"allowedValues": ["AuditIfNotExists", "Disabled"],
"defaultValue": "AuditIfNotExists"
}
},
"policyRule": {
"if": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.Sql/servers"
},
{
"field": "kind",
"notContains": "analytics"
}
]
},
"then": {
"effect": "[parameters('effect')]",
"details": {
"type": "Microsoft.Sql/servers/advancedThreatProtectionSettings",
"name": "Default",
"evaluationDelay": "AfterProvisioning",
"existenceCondition": {
"field": "Microsoft.Sql/servers/advancedThreatProtectionSettings/state",
"equals": "Enabled"
}
}
}
}
}
}
ポリシー 2:Azure SQL Managed Instance 用(combined-policy-mi.json)
{
"$schema": "https://schema.management.azure.com/schemas/2019-09-01/policyDefinition.json#",
"name": "custom-defender-for-sql-mi-resource-audit",
"properties": {
"displayName": "[Custom] Defender for SQL (Azure SQL Managed Instance) - Resource Level Audit",
"policyType": "Custom",
"mode": "All",
"description": "各 Azure SQL Managed Instance(Microsoft.Sql/managedInstances)に対して、Defender for SQL がリソース単位(state: Enabled)で有効化されていることを監査します。",
"metadata": {
"version": "1.0.0",
"category": "Security Center"
},
"parameters": {
"effect": {
"type": "String",
"metadata": {
"displayName": "Effect",
"description": "AuditIfNotExists または Disabled"
},
"allowedValues": ["AuditIfNotExists", "Disabled"],
"defaultValue": "AuditIfNotExists"
}
},
"policyRule": {
"if": {
"field": "type",
"equals": "Microsoft.Sql/managedInstances"
},
"then": {
"effect": "[parameters('effect')]",
"details": {
"type": "Microsoft.Sql/managedInstances/advancedThreatProtectionSettings",
"name": "Default",
"evaluationDelay": "AfterProvisioning",
"existenceCondition": {
"field": "Microsoft.Sql/managedInstances/advancedThreatProtectionSettings/state",
"equals": "Enabled"
}
}
}
}
}
}
動作フローは以下の通りです。
【Azure SQL Database】
Microsoft.Sql/servers が存在する(Synapse Analytics を除く)
└─ advancedThreatProtectionSettings/Default の state == Enabled か?
├─ YES → Compliant ✅
└─ NO → NonCompliant ❌(AuditIfNotExists)
【Azure SQL Managed Instance】
Microsoft.Sql/managedInstances が存在する
└─ advancedThreatProtectionSettings/Default の state == Enabled か?
├─ YES → Compliant ✅
└─ NO → NonCompliant ❌(AuditIfNotExists)
kind notContains "analytics" の条件は、Synapse Dedicated SQL Pool を SQL DB ポリシーの対象から除外するためのものです。Synapse については別途专用ポリシー(ポリシー 3・4)で監査します。
Synapse Workspace の子リソース型は advancedThreatProtectionSettings ではなく securityAlertPolicies である点に注意してください(ビルトインポリシー ID: d31e5c31-63b2-4f12-887b-e49456834fa1 を参考)。
ポリシー 3:Synapse Dedicated SQL Pool 用(combined-policy-synapse-dedicated.json)
{
"$schema": "https://schema.management.azure.com/schemas/2019-09-01/policyDefinition.json#",
"name": "custom-defender-for-synapse-ded-audit",
"properties": {
"displayName": "[Custom] Defender for SQL (Synapse Dedicated SQL Pool) - Resource Level Audit",
"policyType": "Custom",
"mode": "All",
"description": "旧来の Synapse Analytics 専用 SQL プール(Microsoft.Sql/servers の kind に analytics を含む)に対して、Defender for SQL がリソース単位(state: Enabled)で有効化されていることを監査します。",
"metadata": { "version": "1.0.0", "category": "Security Center" },
"parameters": {
"effect": {
"type": "String",
"metadata": { "displayName": "Effect", "description": "AuditIfNotExists または Disabled" },
"allowedValues": ["AuditIfNotExists", "Disabled"],
"defaultValue": "AuditIfNotExists"
}
},
"policyRule": {
"if": {
"allOf": [
{ "field": "type", "equals": "Microsoft.Sql/servers" },
{ "field": "kind", "contains": "analytics" }
]
},
"then": {
"effect": "[parameters('effect')]",
"details": {
"type": "Microsoft.Sql/servers/advancedThreatProtectionSettings",
"name": "Default",
"evaluationDelay": "AfterProvisioning",
"existenceCondition": {
"field": "Microsoft.Sql/servers/advancedThreatProtectionSettings/state",
"equals": "Enabled"
}
}
}
}
}
}
ポリシー 4:Synapse Workspace 用(combined-policy-synapse-workspace.json)
{
"$schema": "https://schema.management.azure.com/schemas/2019-09-01/policyDefinition.json#",
"name": "custom-defender-for-synapse-ws-audit",
"properties": {
"displayName": "[Custom] Defender for SQL (Synapse Workspace) - Resource Level Audit",
"policyType": "Custom",
"mode": "All",
"description": "各 Azure Synapse Analytics ワークスペース(Microsoft.Synapse/workspaces)に対して、Defender for SQL がリソース単位(state: Enabled)で有効化されていることを監査します。",
"metadata": { "version": "1.0.0", "category": "Security Center" },
"parameters": {
"effect": {
"type": "String",
"metadata": { "displayName": "Effect", "description": "AuditIfNotExists または Disabled" },
"allowedValues": ["AuditIfNotExists", "Disabled"],
"defaultValue": "AuditIfNotExists"
}
},
"policyRule": {
"if": {
"field": "type",
"equals": "Microsoft.Synapse/workspaces"
},
"then": {
"effect": "[parameters('effect')]",
"details": {
"type": "Microsoft.Synapse/workspaces/securityAlertPolicies",
"name": "Default",
"evaluationDelay": "AfterProvisioning",
"existenceCondition": {
"field": "Microsoft.Synapse/workspaces/securityAlertPolicies/state",
"equals": "Enabled"
}
}
}
}
}
}
動作フローは以下の通りです。
【Azure SQL Database】
Microsoft.Sql/servers が存在する(Synapse Analytics を除く)
└─ advancedThreatProtectionSettings/Default の state == Enabled か?
├─ YES → Compliant ✅
└─ NO → NonCompliant ❌(AuditIfNotExists)
【Azure SQL Managed Instance】
Microsoft.Sql/managedInstances が存在する
└─ advancedThreatProtectionSettings/Default の state == Enabled か?
├─ YES → Compliant ✅
└─ NO → NonCompliant ❌(AuditIfNotExists)
【Synapse Dedicated SQL Pool】
Microsoft.Sql/servers(kind に analytics を含む)が存在する
└─ advancedThreatProtectionSettings/Default の state == Enabled か?
├─ YES → Compliant ✅
└─ NO → NonCompliant ❌(AuditIfNotExists)
【Synapse Workspace】
Microsoft.Synapse/workspaces が存在する
└─ securityAlertPolicies/Default の state == Enabled か?
├─ YES → Compliant ✅
└─ NO → NonCompliant ❌(AuditIfNotExists)
evaluationDelay: AfterProvisioning を指定しているため、新規作成直後のリソースが不当に NonCompliant になるケースを防いでいます。
4.2 Azure へのデプロイ - ARM テンプレートを使う方法(推奨)
ARM テンプレート(azuredeploy.json)を用意することで、4 つのポリシー定義と割り当てを 1 回のデプロイで展開できます。
Azure CLI を用いる場合は以下のコマンドでデプロイします。
$mgId = "<Tenant Root Group ID>" # 例: テナントIDと同じ値
az deployment mg create `
--name "deploy-defender-sql-policy" `
--management-group-id $mgId `
--location japaneast `
--template-file azuredeploy.json `
--parameters azuredeploy.parameters.json
パラメーターは以下の2つです。
| パラメーター | デフォルト | 説明 |
|---|---|---|
policyEffect |
AuditIfNotExists |
ポリシーの Effect(4 ポリシー共通) |
assignPolicy |
true |
true にすると定義作成と同時に管理グループへ割り当ても実施 |
4.3 Azure CLI で直接デプロイする方法
ARM テンプレートを使わず、Azure CLI で直接デプロイすることもできます。
$mgId = "<Tenant Root Group ID>"
# ─── Azure SQL Database 用 ───
$policy = Get-Content "combined-policy.json" -Raw | ConvertFrom-Json
$policy.properties.policyRule | ConvertTo-Json -Depth 10 | Out-File "$env:TEMP\policy-rule-db.json" -Encoding utf8
$policy.properties.parameters | ConvertTo-Json -Depth 10 | Out-File "$env:TEMP\policy-params-db.json" -Encoding utf8
az policy definition create `
--name "custom-defender-for-sql-db-resource-audit" `
--rules "$env:TEMP\policy-rule-db.json" `
--params "$env:TEMP\policy-params-db.json" `
--mode All `
--display-name "[Custom] Defender for SQL (Azure SQL Database) - Resource Level Audit" `
--management-group $mgId
az policy assignment create `
--name "dfsql-db-resource-audit" `
--display-name "[Custom] Defender for SQL (Azure SQL Database) - Resource Level Audit" `
--policy "/providers/Microsoft.Management/managementGroups/$mgId/providers/Microsoft.Authorization/policyDefinitions/custom-defender-for-sql-db-resource-audit" `
--scope "/providers/Microsoft.Management/managementGroups/$mgId" `
--enforcement-mode Default
# ─── Azure SQL Managed Instance 用 ───
$policyMi = Get-Content "combined-policy-mi.json" -Raw | ConvertFrom-Json
$policyMi.properties.policyRule | ConvertTo-Json -Depth 10 | Out-File "$env:TEMP\policy-rule-mi.json" -Encoding utf8
$policyMi.properties.parameters | ConvertTo-Json -Depth 10 | Out-File "$env:TEMP\policy-params-mi.json" -Encoding utf8
az policy definition create `
--name "custom-defender-for-sql-mi-resource-audit" `
--rules "$env:TEMP\policy-rule-mi.json" `
--params "$env:TEMP\policy-params-mi.json" `
--mode All `
--display-name "[Custom] Defender for SQL (Azure SQL Managed Instance) - Resource Level Audit" `
--management-group $mgId
az policy assignment create `
--name "dfsql-mi-resource-audit" `
--display-name "[Custom] Defender for SQL (Azure SQL Managed Instance) - Resource Level Audit" `
--policy "/providers/Microsoft.Management/managementGroups/$mgId/providers/Microsoft.Authorization/policyDefinitions/custom-defender-for-sql-mi-resource-audit" `
--scope "/providers/Microsoft.Management/managementGroups/$mgId" `
--enforcement-mode Default
# ─── Synapse Dedicated SQL Pool 用 ───
$policySynDed = Get-Content "combined-policy-synapse-dedicated.json" -Raw | ConvertFrom-Json
$policySynDed.properties.policyRule | ConvertTo-Json -Depth 10 | Out-File "$env:TEMP\policy-rule-syn-ded.json" -Encoding utf8
$policySynDed.properties.parameters | ConvertTo-Json -Depth 10 | Out-File "$env:TEMP\policy-params-syn-ded.json" -Encoding utf8
az policy definition create `
--name "custom-defender-for-synapse-ded-audit" `
--rules "$env:TEMP\policy-rule-syn-ded.json" `
--params "$env:TEMP\policy-params-syn-ded.json" `
--mode All `
--display-name "[Custom] Defender for SQL (Synapse Dedicated SQL Pool) - Resource Level Audit" `
--management-group $mgId
az policy assignment create `
--name "dfsql-syn-ded-audit" `
--display-name "[Custom] Defender for SQL (Synapse Dedicated SQL Pool) - Resource Level Audit" `
--policy "/providers/Microsoft.Management/managementGroups/$mgId/providers/Microsoft.Authorization/policyDefinitions/custom-defender-for-synapse-ded-audit" `
--scope "/providers/Microsoft.Management/managementGroups/$mgId" `
--enforcement-mode Default
# ─── Synapse Workspace 用 ───
$policySynWs = Get-Content "combined-policy-synapse-workspace.json" -Raw | ConvertFrom-Json
$policySynWs.properties.policyRule | ConvertTo-Json -Depth 10 | Out-File "$env:TEMP\policy-rule-syn-ws.json" -Encoding utf8
$policySynWs.properties.parameters | ConvertTo-Json -Depth 10 | Out-File "$env:TEMP\policy-params-syn-ws.json" -Encoding utf8
az policy definition create `
--name "custom-defender-for-synapse-ws-audit" `
--rules "$env:TEMP\policy-rule-syn-ws.json" `
--params "$env:TEMP\policy-params-syn-ws.json" `
--mode All `
--display-name "[Custom] Defender for SQL (Synapse Workspace) - Resource Level Audit" `
--management-group $mgId
az policy assignment create `
--name "dfsql-syn-ws-audit" `
--display-name "[Custom] Defender for SQL (Synapse Workspace) - Resource Level Audit" `
--policy "/providers/Microsoft.Management/managementGroups/$mgId/providers/Microsoft.Authorization/policyDefinitions/custom-defender-for-synapse-ws-audit" `
--scope "/providers/Microsoft.Management/managementGroups/$mgId" `
--enforcement-mode Default
az policy definition create に JSON ファイル全体(name や properties を含む)を渡すとエラーになります。--rules には policyRule の中身のみ、--params には parameters の中身のみを渡す必要があります。
ポリシー割り当て名(--name)は 24文字以内 という制限があります。
4.4 オンデマンドでコンプライアンス評価を実行する
通常の評価サイクルは約24時間ですが、az policy state trigger-scan で即時評価をトリガーできます。
# 同期実行(完了まで待機)
az policy state trigger-scan --subscription <Subscription ID>
# SQL Database の結果確認
az policy state list `
--subscription <Subscription ID> `
--filter "policyAssignmentName eq 'dfsql-db-resource-audit'" `
--query "[].{resource:resourceId, compliant:complianceState}" `
-o table
# SQL Managed Instance の結果確認
az policy state list `
--subscription <Subscription ID> `
--filter "policyAssignmentName eq 'dfsql-mi-resource-audit'" `
--query "[].{resource:resourceId, compliant:complianceState}" `
-o table
# Synapse Dedicated SQL Pool の結果確認
az policy state list `
--subscription <Subscription ID> `
--filter "policyAssignmentName eq 'dfsql-syn-ded-audit'" `
--query "[].{resource:resourceId, compliant:complianceState}" `
-o table
# Synapse Workspace の結果確認
az policy state list `
--subscription <Subscription ID> `
--filter "policyAssignmentName eq 'dfsql-syn-ws-audit'" `
--query "[].{resource:resourceId, compliant:complianceState}" `
-o table
--no-wait(非同期)でトリガーした場合、スキャン完了前に結果を取得すると古いキャッシュの値が返ることがあります。正確な結果が必要な場合は同期実行を推奨します。
個別リソースの設定確認
NonCompliant と表示されたリソースの実際の設定値を直接確認する場合は REST API を使います。
# Azure SQL Database(SQL Server)の場合
az rest --method get `
--url "https://management.azure.com/subscriptions/<Sub>/resourceGroups/<RG>/providers/Microsoft.Sql/servers/<ServerName>/advancedThreatProtectionSettings/Default?api-version=2023-08-01"
# Azure SQL Managed Instance の場合
az rest --method get `
--url "https://management.azure.com/subscriptions/<Sub>/resourceGroups/<RG>/providers/Microsoft.Sql/managedInstances/<MiName>/advancedThreatProtectionSettings/Default?api-version=2023-08-01"
# Synapse Dedicated SQL Pool(SQL Server 扱い)の場合
az rest --method get `
--url "https://management.azure.com/subscriptions/<Sub>/resourceGroups/<RG>/providers/Microsoft.Sql/servers/<ServerName>/advancedThreatProtectionSettings/Default?api-version=2023-08-01"
# Synapse Workspace の場合
az rest --method get `
--url "https://management.azure.com/subscriptions/<Sub>/resourceGroups/<RG>/providers/Microsoft.Synapse/workspaces/<WorkspaceName>/securityAlertPolicies/Default?api-version=2021-06-01"
5. サブスクリプション単位との組み合わせ監査
サブスクリプション一括で Defender for SQL を有効化している環境では、リソース単位の advancedThreatProtectionSettings/state が New(未設定)のまま実質的に保護されている SQL Server が存在します。本ポリシー単独ではそのリソースも NonCompliant と判定します。
「どちらかが有効であれば OK」という判断をしたい場合は、以下の3ポリシーを Initiative(イニシアティブ) にまとめて運用します。
| # | 種別 | ポリシー | チェック内容 |
|---|---|---|---|
| 1 | ビルトイン |
Azure Defender for SQL should be enabled for unprotected Azure SQL servers(ID: abfb4388-5bf4-4ad7-ba82-2cd2f41ceae9) |
サブスクリプション単位(securityAlertPolicies/state == Enabled) |
| 2 | カスタム | custom-defender-for-sql-db-resource-audit |
リソース単位 SQL DB(advancedThreatProtectionSettings/state == Enabled) |
| 3 | カスタム | custom-defender-for-sql-mi-resource-audit |
リソース単位 SQL MI(advancedThreatProtectionSettings/state == Enabled) |
| 4 | カスタム | custom-defender-for-synapse-ded-audit |
リソース単位 Synapse Dedicated(advancedThreatProtectionSettings/state == Enabled) |
| 5 | カスタム | custom-defender-for-synapse-ws-audit |
リソース単位 Synapse Workspace(securityAlertPolicies/state == Enabled) |
5.1 コンプライアンス状態の読み方
Azure Policy はイニシアティブ内での「OR 条件」を直接サポートしていません。各ポリシーの結果を手動で突き合わせることで、真の未対応対象を特定します。
サブスク単位(#1) SQL DB(#2) SQL MI(#3) Syn Ded(#4) Syn WS(#5) 解釈
──────────────────────────────────────────────────────────────────────────────────────────
Compliant Compliant Compliant Compliant Compliant ✅ 全レベルで有効
Compliant NonCompliant - NonCompliant - ✅ サブスク有効(実質保護中)
NonCompliant Compliant Compliant Compliant Compliant ✅ リソース単位で個別有効化済み
NonCompliant NonCompliant NonCompliant NonCompliant NonCompliant ❌ どのレベルも未設定 → 要対応
Azure Policy はイニシアティブ内での「OR 条件」を直接サポートしていません。上記の解釈は各ポリシーの結果を手動で突き合わせる運用を前提としています。
5.2 Initiative の作成例
$mgId = "<Tenant Root Group ID>"
$initiative = @{
properties = @{
displayName = "[Custom] Defender for SQL - Combined Audit"
description = "Defender for SQL のリソース単位・サブスクリプション単位の両方の有効化状態を監査します。"
metadata = @{ category = "Security Center"; version = "1.0.0" }
policyDefinitions = @(
@{
policyDefinitionId = "/providers/Microsoft.Authorization/policyDefinitions/abfb4388-5bf4-4ad7-ba82-2cd2f41ceae9"
policyDefinitionReferenceId = "defenderSqlSubscriptionLevel"
parameters = @{ effect = @{ value = "AuditIfNotExists" } }
},
@{
policyDefinitionId = "/providers/Microsoft.Management/managementGroups/$mgId/providers/Microsoft.Authorization/policyDefinitions/custom-defender-for-sql-db-resource-audit"
policyDefinitionReferenceId = "defenderSqlDbResourceLevel"
parameters = @{ effect = @{ value = "AuditIfNotExists" } }
},
@{
policyDefinitionId = "/providers/Microsoft.Management/managementGroups/$mgId/providers/Microsoft.Authorization/policyDefinitions/custom-defender-for-sql-mi-resource-audit"
policyDefinitionReferenceId = "defenderSqlMiResourceLevel"
parameters = @{ effect = @{ value = "AuditIfNotExists" } }
},
@{
policyDefinitionId = "/providers/Microsoft.Management/managementGroups/$mgId/providers/Microsoft.Authorization/policyDefinitions/custom-defender-for-synapse-ded-audit"
policyDefinitionReferenceId = "defenderSynapseDedicatedResourceLevel"
parameters = @{ effect = @{ value = "AuditIfNotExists" } }
},
@{
policyDefinitionId = "/providers/Microsoft.Management/managementGroups/$mgId/providers/Microsoft.Authorization/policyDefinitions/custom-defender-for-synapse-ws-audit"
policyDefinitionReferenceId = "defenderSynapseWorkspaceResourceLevel"
parameters = @{ effect = @{ value = "AuditIfNotExists" } }
}
)
}
} | ConvertTo-Json -Depth 20
$initiative | Out-File "$env:TEMP\initiative.json" -Encoding utf8
az policy set-definition create `
--name "custom-defender-for-sql-combined" `
--definitions "$env:TEMP\initiative.json" `
--management-group $mgId `
--display-name "[Custom] Defender for SQL - Combined Audit"
6. まとめ
-
Azure SQL Database、Azure SQL Managed Instance、Synapse Dedicated SQL Pool、Synapse Workspace はリソース型が異なるため、リソース単位の Defender for SQL 有効化を監査するには 4つのカスタムポリシーが必要
-
チェック対象の子リソース型はそれぞれ
Microsoft.Sql/servers/advancedThreatProtectionSettings(SQL DB)、Microsoft.Sql/managedInstances/advancedThreatProtectionSettings(SQL MI)、Microsoft.Sql/servers/advancedThreatProtectionSettings(Synapse Dedicated)、Microsoft.Synapse/workspaces/securityAlertPolicies(Synapse Workspace)であり、state == Enabledかどうかを評価する -
Synapse Workspace の子リソース型は他の SQL リソースと異なり
securityAlertPoliciesである点に注意(ビルトインポリシーd31e5c31-63b2-4f12-887b-e49456834fa1を参考に確認) -
kind notContains "analytics"の除外条件により、Synapse Dedicated SQL Pool は SQL DB ポリシーから除外し、専用ポリシーで個別監査する設計にしている -
1つのポリシーで「サブスクリプション単位 OR リソース単位」を正確に判定するのは構造上困難なため、5つのポリシーを Initiative でまとめる運用アプローチが現実的
-
az policy state trigger-scanでオンデマンド評価が可能(非同期ではなく同期実行推奨) -
ARM テンプレートを用意しておくと、Deploy to Azure ボタンでワンクリックデプロイが可能
本記事がどなたかの参考になれば幸いです。
*本稿は、個人の見解に基づいた内容であり、所属する会社の公式見解ではありません。また、いかなる保証を与えるものでもありません。正式な情報は、各製品の販売元にご確認ください。
参考情報
- Microsoft Defender for SQL とは
- Microsoft.Sql/servers/advancedThreatProtectionSettings - ARM テンプレートリファレンス
- Microsoft.Sql/managedInstances/advancedThreatProtectionSettings - ARM テンプレートリファレンス
- Microsoft.Synapse/workspaces/securityAlertPolicies - ARM テンプレートリファレンス
- Azure Policy の定義の構造
- AuditIfNotExists の効果
- Azure Policy のコンプライアンス評価をトリガーする
- GitHub - Check-DefenderForSQL--ResourceLevel