diff --git a/samples/manage/azure-arc-enabled-sql-server/compliance/README.md b/samples/manage/azure-arc-enabled-sql-server/compliance/README.md index 0dce23fe..9d80aefb 100644 --- a/samples/manage/azure-arc-enabled-sql-server/compliance/README.md +++ b/samples/manage/azure-arc-enabled-sql-server/compliance/README.md @@ -1,6 +1,6 @@ # Paygo-SQLArc (Windows only) -This Azure Policy ensures that all SQL Arc servers using `LicenseType = Paid` are marked as non-compliant. Servers with `LicenseType = LicenseOnly` are treated as compliant. The remediated task sets `LicenseType = PAYG`. +This Azure Policy ensures that all SQL Arc servers using `LicenseType = Paid` are marked as non-compliant. Servers with `LicenseType = LicenseOnly` are treated as compliant. The remediation task sets `LicenseType = PAYG`. Use Azure CLI or PowerShell to create the policy definition: @@ -20,7 +20,7 @@ Use the following command to create policy az policy definition create \ --name "Paygo-SQLArc" \ --display-name "Paygo-SQLArc" \ - --description "This Azure Policy ensures that all SQL Arc servers using LicenseType = Paid are marked as non-compliant. Servers with LicenseType = LicenseOnly are treated as compliant. The remediated task sets LicenseType = PAYG." \ + --description "This Azure Policy ensures that all SQL Arc servers using LicenseType = Paid are marked as non-compliant. Servers with LicenseType = LicenseOnly are treated as compliant. The remediation task sets LicenseType = PAYG." \ --rules @rules.json \ --params @params.json \ --mode Indexed \ diff --git a/samples/manage/azure-hybrid-benefit/compliance/azure-sql-payg-compliance/sql-mi-payg-compliance/README.md b/samples/manage/azure-hybrid-benefit/compliance/azure-sql-payg-compliance/sql-mi-payg-compliance/README.md new file mode 100644 index 00000000..8655b5c1 --- /dev/null +++ b/samples/manage/azure-hybrid-benefit/compliance/azure-sql-payg-compliance/sql-mi-payg-compliance/README.md @@ -0,0 +1,69 @@ +# Paygo-SQLMI + +This Azure Policy ensures that all SQL Managed Instance resources using `LicenseType = BasePrice` are marked as non-compliant. The remediation task sets `LicenseType = LicenseIncluded`. + +Use Azure CLI or PowerShell to create the policy definition: + +## Artifacts + +- **policy.json**: Main policy definition referencing external parameter and rule files. +- **params.json**: Defines policy parameters. +- **rules.json**: Contains the policy rule logic. + +## Create policy +Use the following command to create policy + +```bash + +#!/bin/bash + +az policy definition create \ + --name "Paygo-SQLArc" \ + --display-name "Paygo-SQLMI" \ + --description "This Azure Policy ensures that all SQL Managed Instance resources using LicenseType = BasePrice are marked as non-compliant. The remediation task sets LicenseType = LicenseIncluded." \ + --rules @rules.json \ + --params @params.json \ + --mode Indexed \ + --subscription ""\ +``` + +## Assign policy + +Use the following command to assign policy + +```bash +#!/bin/bash + +# Set variables +SUB_ID="" +RG_NAME="" # optional +SCOPE="/subscriptions/$SUB_ID/resourceGroups/$RG_NAME" +LOCATION="" + +# Create policy assignment +az policy assignment create \ + --name "Paygo-SQLMI-Assign" \ + --policy "Paygo-SQLArc" \ + --scope "$SCOPE" \ + --params '{ "effect": { "value": "DeployIfNotExists" } }' \ + --mi-system-assigned \ + --role "Contributor" \ + --identity-scope "$SCOPE" \ + --location "$LOCATION" +``` + +## Create remediation task + +Us the following command to create a remediation task + +```bash +#!/bin/bash + +RG_NAME="" + +az policy remediation create \ + --name "Remediate-Paygo-SQLMI" \ + --policy-assignment "Paygo-SQLMI-Assign" \ + --resource-group "$RG_NAME" \ + --resource-discovery-mode ReEvaluateCompliance +``` diff --git a/samples/manage/azure-hybrid-benefit/compliance/azure-sql-payg-compliance/sql-mi-payg-compliance/params.json b/samples/manage/azure-hybrid-benefit/compliance/azure-sql-payg-compliance/sql-mi-payg-compliance/params.json new file mode 100644 index 00000000..390e5440 --- /dev/null +++ b/samples/manage/azure-hybrid-benefit/compliance/azure-sql-payg-compliance/sql-mi-payg-compliance/params.json @@ -0,0 +1,16 @@ +{ + "parameters": { + "effect": { + "type": "String", + "metadata": { + "displayName": "Effect", + "description": "Use DeployIfNotExists to remediate; use Disabled to turn off." + }, + "allowedValues": [ + "DeployIfNotExists", + "Disabled" + ], + "defaultValue": "DeployIfNotExists" + } + } +} \ No newline at end of file diff --git a/samples/manage/azure-hybrid-benefit/compliance/azure-sql-payg-compliance/sql-mi-payg-compliance/policy.json b/samples/manage/azure-hybrid-benefit/compliance/azure-sql-payg-compliance/sql-mi-payg-compliance/policy.json new file mode 100644 index 00000000..51013033 --- /dev/null +++ b/samples/manage/azure-hybrid-benefit/compliance/azure-sql-payg-compliance/sql-mi-payg-compliance/policy.json @@ -0,0 +1,118 @@ +{ + "properties": { + "displayName": "Paygo-SQLMI", + "policyType": "Custom", + "mode": "Indexed", + "description": "Ensures SQL Managed Instance uses PAYG licensing. If a managed instance is created/updated with Azure Hybrid Benefit ('BasePrice'), this policy modifies licenseType to 'LicenseIncluded' (PAYG). The remediation is compliant with the Entra‑only authentication initiative", + "metadata": { + "version": "1.0.0", + "category": "SQL", + "source": "github.com/your-org/azure-policy-paygo-sqlmi" + }, + "parameters": { + "effect": { + "type": "String", + "metadata": { + "displayName": "Effect", + "description": "Use DeployIfNotExists to remediate; use Disabled to turn off." + }, + "allowedValues": [ + "DeployIfNotExists", + "Disabled" + ], + "defaultValue": "DeployIfNotExists" + } + }, + "policyRule": { + "if": { + "allOf": [ + { + "field": "type", + "equals": "Microsoft.Sql/managedInstances" + } + ] + }, + "then": { + "effect": "[parameters('effect')]", + "details": { + "type": "Microsoft.Sql/managedInstances", + "name": "[field('name')]", + "roleDefinitionIds": [ + "/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c" + ], + "evaluationDelay": "AfterProvisioningSuccess", + "existenceCondition": { + "allOf": [ + { + "field": "Microsoft.Sql/managedInstances/licenseType", + "equals": "LicenseIncluded" + }, + { + "field": "Microsoft.Sql/managedInstances/administrators.azureADOnlyAuthentication", + "equals": true + } + ] + }, + "deployment": { + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "miName": { "type": "string" }, + "location": { "type": "string" } + }, + "resources": [ + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "updateMiAdminAndLicense", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "miName": { "type": "string" }, + "location": { "type": "string" } + }, + "resources": [ + { + "type": "Microsoft.Sql/managedInstances", + "apiVersion": "2023-08-01", + "name": "[parameters('miName')]", + "location": "[parameters('location')]", + "properties": { + "licenseType": "LicenseIncluded", + "administrators": { + "administratorType": "ActiveDirectory", + "principalType": "Application", + "login": "[parameters('miName')]", + "sid": "[reference(resourceId('Microsoft.Sql/managedInstances', parameters('miName')), '2023-08-01', 'Full').identity.principalId]", + "tenantId": "[subscription().tenantId]", + "azureADOnlyAuthentication": true + } + } + } + ] + }, + "parameters": { + "miName": { "value": "[parameters('miName')]" }, + "location": { "value": "[parameters('location')]" } + } + } + } + ] + }, + "parameters": { + "miName": { "value": "[field('name')]" }, + "location": { "value": "[field('location')]" } + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/samples/manage/azure-hybrid-benefit/compliance/azure-sql-payg-compliance/sql-mi-payg-compliance/rules.json b/samples/manage/azure-hybrid-benefit/compliance/azure-sql-payg-compliance/sql-mi-payg-compliance/rules.json new file mode 100644 index 00000000..db6516b0 --- /dev/null +++ b/samples/manage/azure-hybrid-benefit/compliance/azure-sql-payg-compliance/sql-mi-payg-compliance/rules.json @@ -0,0 +1,93 @@ +{ + "policyRule": { + "if": { + "allOf": [ + { + "field": "type", + "equals": "Microsoft.Sql/managedInstances" + } + ] + }, + "then": { + "effect": "[parameters('effect')]", + "details": { + "type": "Microsoft.Sql/managedInstances", + "name": "[field('name')]", + "roleDefinitionIds": [ + "/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c" + ], + "evaluationDelay": "AfterProvisioningSuccess", + "existenceCondition": { + "allOf": [ + { + "field": "Microsoft.Sql/managedInstances/licenseType", + "equals": "LicenseIncluded" + }, + { + "field": "Microsoft.Sql/managedInstances/administrators.azureADOnlyAuthentication", + "equals": true + } + ] + }, + "deployment": { + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "miName": { "type": "string" }, + "location": { "type": "string" } + }, + "resources": [ + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "updateMiAdminAndLicense", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "miName": { "type": "string" }, + "location": { "type": "string" } + }, + "resources": [ + { + "type": "Microsoft.Sql/managedInstances", + "apiVersion": "2023-08-01", + "name": "[parameters('miName')]", + "location": "[parameters('location')]", + "properties": { + "licenseType": "LicenseIncluded", + "administrators": { + "administratorType": "ActiveDirectory", + "principalType": "Application", + "login": "[parameters('miName')]", + "sid": "[reference(resourceId('Microsoft.Sql/managedInstances', parameters('miName')), '2023-08-01', 'Full').identity.principalId]", + "tenantId": "[subscription().tenantId]", + "azureADOnlyAuthentication": true + } + } + } + ] + }, + "parameters": { + "miName": { "value": "[parameters('miName')]" }, + "location": { "value": "[parameters('location')]" } + } + } + } + ] + }, + "parameters": { + "miName": { "value": "[field('name')]" }, + "location": { "value": "[field('location')]" } + } + } + } + } + } + } +} \ No newline at end of file