0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Azure SQL データベースでリソースレベルで Defender for SQL が有効になっているか監視する

0
Last updated at Posted at 2026-03-31

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/serverskindanalytics を含む) 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(kindanalytics を含む)も含まれますが、SQL DB ポリシーでは除外し、代わりに Synapse Dedicated 専用ポリシーで個別に監査します。また、Synapse Workspace は子リソース型が securityAlertPoliciesadvancedThreatProtectionSettings ではない)のため別ポリシーが必要です。


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 回のデプロイで展開できます。

Deploy to Azure

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 ファイル全体(nameproperties を含む)を渡すとエラーになります。--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/stateNew(未設定)のまま実質的に保護されている 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 ボタンでワンクリックデプロイが可能

本記事がどなたかの参考になれば幸いです。

*本稿は、個人の見解に基づいた内容であり、所属する会社の公式見解ではありません。また、いかなる保証を与えるものでもありません。正式な情報は、各製品の販売元にご確認ください。


参考情報

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?