From 95179b9ea18862d8d25071e1a99fc3e7ddd8a942 Mon Sep 17 00:00:00 2001 From: "Alexander (Sasha) Nosov" Date: Fri, 24 Oct 2025 16:13:09 -0700 Subject: [PATCH 1/2] Add Payg-SQLArc policy --- .../monitor-compliance/README.md | 69 ++++++++++++ .../arc-sql-payg-compliance/params.json | 14 +++ .../arc-sql-payg-compliance/policy.json | 14 +++ .../arc-sql-payg-compliance/rules.json | 98 ++++++++++++++++++ .../ModifiedResources_20251013_203148.csv | 6 ++ .../ModifiedResources_20251013_210723.csv | 8 ++ .../ModifiedResources_20251013_211053.csv | 2 + .../ModifiedResources_20251013_213825.csv | 2 + .../modify-license-type/Paygo-SQLArc.json | Bin 0 -> 10994 bytes .../modify-license-type/README.md | 2 +- 10 files changed, 214 insertions(+), 1 deletion(-) create mode 100644 samples/manage/azure-arc-enabled-sql-server/monitor-compliance/README.md create mode 100644 samples/manage/azure-arc-enabled-sql-server/monitor-compliance/arc-sql-payg-compliance/params.json create mode 100644 samples/manage/azure-arc-enabled-sql-server/monitor-compliance/arc-sql-payg-compliance/policy.json create mode 100644 samples/manage/azure-arc-enabled-sql-server/monitor-compliance/arc-sql-payg-compliance/rules.json create mode 100644 samples/manage/azure-hybrid-benefit/modify-license-type/ModifiedResources_20251013_203148.csv create mode 100644 samples/manage/azure-hybrid-benefit/modify-license-type/ModifiedResources_20251013_210723.csv create mode 100644 samples/manage/azure-hybrid-benefit/modify-license-type/ModifiedResources_20251013_211053.csv create mode 100644 samples/manage/azure-hybrid-benefit/modify-license-type/ModifiedResources_20251013_213825.csv create mode 100644 samples/manage/azure-hybrid-benefit/modify-license-type/Paygo-SQLArc.json diff --git a/samples/manage/azure-arc-enabled-sql-server/monitor-compliance/README.md b/samples/manage/azure-arc-enabled-sql-server/monitor-compliance/README.md new file mode 100644 index 0000000000..0dce23fede --- /dev/null +++ b/samples/manage/azure-arc-enabled-sql-server/monitor-compliance/README.md @@ -0,0 +1,69 @@ +# 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`. + +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-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." \ + --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-SQLArc-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-SQLArc" \ + --policy-assignment "Paygo-SQLArc-Assign" \ + --resource-group "$RG_NAME" \ + --resource-discovery-mode ReEvaluateCompliance +``` diff --git a/samples/manage/azure-arc-enabled-sql-server/monitor-compliance/arc-sql-payg-compliance/params.json b/samples/manage/azure-arc-enabled-sql-server/monitor-compliance/arc-sql-payg-compliance/params.json new file mode 100644 index 0000000000..eaedc9550f --- /dev/null +++ b/samples/manage/azure-arc-enabled-sql-server/monitor-compliance/arc-sql-payg-compliance/params.json @@ -0,0 +1,14 @@ +{ + "effect": { + "type": "String", + "metadata": { + "displayName": "Effect", + "description": "Enable or disable the execution of the policy." + }, + "allowedValues": [ + "DeployIfNotExists", + "Disabled" + ], + "defaultValue": "DeployIfNotExists" + } +} \ No newline at end of file diff --git a/samples/manage/azure-arc-enabled-sql-server/monitor-compliance/arc-sql-payg-compliance/policy.json b/samples/manage/azure-arc-enabled-sql-server/monitor-compliance/arc-sql-payg-compliance/policy.json new file mode 100644 index 0000000000..ac6dcdff39 --- /dev/null +++ b/samples/manage/azure-arc-enabled-sql-server/monitor-compliance/arc-sql-payg-compliance/policy.json @@ -0,0 +1,14 @@ +{ + "properties": { + "displayName": "Paygo-SQLArc (Windows only)", + "policyType": "Custom", + "mode": "Indexed", + "description": "Policy to replace all SQL Arc server that use License type = 'Paid' with License type = 'PAYG'. Treat License type = 'LicenseOnly' as compliant", + "metadata": { + "category": "SQLArc", + "version": "1.0.0" + }, + "parameters": "./params.json", + "policyRule": "./rules.json" + } +} \ No newline at end of file diff --git a/samples/manage/azure-arc-enabled-sql-server/monitor-compliance/arc-sql-payg-compliance/rules.json b/samples/manage/azure-arc-enabled-sql-server/monitor-compliance/arc-sql-payg-compliance/rules.json new file mode 100644 index 0000000000..537c2602e9 --- /dev/null +++ b/samples/manage/azure-arc-enabled-sql-server/monitor-compliance/arc-sql-payg-compliance/rules.json @@ -0,0 +1,98 @@ +{ + "if": { + "allOf": [ + { + "equals": "Microsoft.HybridCompute/machines/extensions", + "field": "type" + }, + { + "equals": "Microsoft.AzureData", + "field": "Microsoft.HybridCompute/machines/extensions/publisher" + }, + { + "equals": "WindowsAgent.SqlServer", + "field": "Microsoft.HybridCompute/machines/extensions/type" + } + ] + }, + "then": { + "effect": "[parameters('effect')]", + "details": { + "type": "Microsoft.HybridCompute/machines/extensions", + "roleDefinitionIds": [ + "/providers/Microsoft.Authorization/roleDefinitions/7392c568-9289-4bde-aaaa-b7131215889d", + "/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7" + ], + "name": "[field('fullName')]", + "existenceCondition": { + "anyOf": [ + { + "equals": "[string(createObject('LicenseType','PAYG'))]", + "value": "[string(intersection(if(empty(field('Microsoft.HybridCompute/machines/extensions/settings')), createObject(), field('Microsoft.HybridCompute/machines/extensions/settings')), createObject('LicenseType','PAYG')))]" + }, + { + "equals": "[string(createObject('LicenseType','LicenseOnly'))]", + "value": "[string(intersection(if(empty(field('Microsoft.HybridCompute/machines/extensions/settings')), createObject(), field('Microsoft.HybridCompute/machines/extensions/settings')), createObject('LicenseType','LicenseOnly')))]" + } + ] + }, + "evaluationDelay": "AfterProvisioningSuccess", + "deployment": { + "properties": { + "mode": "incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "extensionName": { + "type": "string" + }, + "vmLocation": { + "type": "string" + }, + "agentName": { + "type": "string" + }, + "existingSettings": { + "type": "object" + } + }, + "variables": { + "vmExtensionPublisher": "Microsoft.AzureData", + "updatedSettings": { + "LicenseType": "PAYG" + } + }, + "resources": [ + { + "name": "[parameters('extensionName')]", + "type": "Microsoft.HybridCompute/machines/extensions", + "location": "[parameters('vmLocation')]", + "apiVersion": "2022-11-10", + "properties": { + "publisher": "[variables('vmExtensionPublisher')]", + "type": "[parameters('agentName')]", + "settings": "[union(parameters('existingSettings'), variables('updatedSettings'))]" + } + } + ] + }, + "parameters": { + "extensionName": { + "value": "[field('fullName')]" + }, + "vmLocation": { + "value": "[field('location')]" + }, + "agentName": { + "value": "[field('name')]" + }, + "existingSettings": { + "value": "[field('Microsoft.HybridCompute/machines/extensions/settings')]" + } + } + } + } + } + } +} \ No newline at end of file diff --git a/samples/manage/azure-hybrid-benefit/modify-license-type/ModifiedResources_20251013_203148.csv b/samples/manage/azure-hybrid-benefit/modify-license-type/ModifiedResources_20251013_203148.csv new file mode 100644 index 0000000000..48c636a1ea --- /dev/null +++ b/samples/manage/azure-hybrid-benefit/modify-license-type/ModifiedResources_20251013_203148.csv @@ -0,0 +1,6 @@ +"TenantID","SubID","ResourceName","ResourceType","Status","OriginalLicenseType","ResourceGroup","Location" +"72f988bf-86f1-41af-91ab-2d7cd011db47","fa58cf66-caaf-4ba9-875d-f310d3694845","SQL2012EEArc","Microsoft.SqlVirtualMachine/sqlVirtualMachines","VM running","AHUB","ajayj","westus2" +"72f988bf-86f1-41af-91ab-2d7cd011db47","fa58cf66-caaf-4ba9-875d-f310d3694845","SQL2022EE","Microsoft.SqlVirtualMachine/sqlVirtualMachines","VM running","AHUB","ajayj","westus2" +"72f988bf-86f1-41af-91ab-2d7cd011db47","fa58cf66-caaf-4ba9-875d-f310d3694845","sql2025devstd","Microsoft.SqlVirtualMachine/sqlVirtualMachines","VM running","AHUB","ajayj","westus2" +"72f988bf-86f1-41af-91ab-2d7cd011db47","fa58cf66-caaf-4ba9-875d-f310d3694845","ajayjsqlmi","Microsoft.Sql/managedInstances","Ready","BasePrice","ajayj","westus2" +"72f988bf-86f1-41af-91ab-2d7cd011db47","fa58cf66-caaf-4ba9-875d-f310d3694845","AdventureworksLT","Microsoft.Sql/servers/databases","Online","BasePrice","ajayj","westus2" diff --git a/samples/manage/azure-hybrid-benefit/modify-license-type/ModifiedResources_20251013_210723.csv b/samples/manage/azure-hybrid-benefit/modify-license-type/ModifiedResources_20251013_210723.csv new file mode 100644 index 0000000000..c2cc0f5fd4 --- /dev/null +++ b/samples/manage/azure-hybrid-benefit/modify-license-type/ModifiedResources_20251013_210723.csv @@ -0,0 +1,8 @@ +"TenantID","SubID","ResourceName","ResourceType","Status","OriginalLicenseType","ResourceGroup","Location" +"72f988bf-86f1-41af-91ab-2d7cd011db47","fa58cf66-caaf-4ba9-875d-f310d3694845","SQL2019Arc","Microsoft.SqlVirtualMachine/sqlVirtualMachines","VM running","PAYG","ajayj","westus2" +"72f988bf-86f1-41af-91ab-2d7cd011db47","fa58cf66-caaf-4ba9-875d-f310d3694845","sql2022rtmdev","Microsoft.SqlVirtualMachine/sqlVirtualMachines","VM running","PAYG","ajayj","westus2" +"72f988bf-86f1-41af-91ab-2d7cd011db47","fa58cf66-caaf-4ba9-875d-f310d3694845","sqldbmi2","Microsoft.Sql/managedInstances","Ready","LicenseIncluded","ajayj","westus" +"72f988bf-86f1-41af-91ab-2d7cd011db47","fa58cf66-caaf-4ba9-875d-f310d3694845","sqldbmi1","Microsoft.Sql/managedInstances","Ready","LicenseIncluded","ajayj","westus" +"72f988bf-86f1-41af-91ab-2d7cd011db47","fa58cf66-caaf-4ba9-875d-f310d3694845","AlwaysEncrypted","Microsoft.Sql/servers/databases","Online","LicenseIncluded","ajayj","westcentralus" +"72f988bf-86f1-41af-91ab-2d7cd011db47","fa58cf66-caaf-4ba9-875d-f310d3694845","dbmirroringspn","Microsoft.Sql/servers/databases","Online","LicenseIncluded","ajayj","westus2" +"72f988bf-86f1-41af-91ab-2d7cd011db47","fa58cf66-caaf-4ba9-875d-f310d3694845","dbmirrortest","Microsoft.Sql/servers/databases","Online","LicenseIncluded","ajayj","westus2" diff --git a/samples/manage/azure-hybrid-benefit/modify-license-type/ModifiedResources_20251013_211053.csv b/samples/manage/azure-hybrid-benefit/modify-license-type/ModifiedResources_20251013_211053.csv new file mode 100644 index 0000000000..654291588b --- /dev/null +++ b/samples/manage/azure-hybrid-benefit/modify-license-type/ModifiedResources_20251013_211053.csv @@ -0,0 +1,2 @@ +"TenantID","SubID","ResourceName","ResourceType","Status","OriginalLicenseType","ResourceGroup","Location" +"72f988bf-86f1-41af-91ab-2d7cd011db47","fa58cf66-caaf-4ba9-875d-f310d3694845","SQL2019Arc","Microsoft.SqlVirtualMachine/sqlVirtualMachines","VM running","PAYG","ajayj","westus2" diff --git a/samples/manage/azure-hybrid-benefit/modify-license-type/ModifiedResources_20251013_213825.csv b/samples/manage/azure-hybrid-benefit/modify-license-type/ModifiedResources_20251013_213825.csv new file mode 100644 index 0000000000..654291588b --- /dev/null +++ b/samples/manage/azure-hybrid-benefit/modify-license-type/ModifiedResources_20251013_213825.csv @@ -0,0 +1,2 @@ +"TenantID","SubID","ResourceName","ResourceType","Status","OriginalLicenseType","ResourceGroup","Location" +"72f988bf-86f1-41af-91ab-2d7cd011db47","fa58cf66-caaf-4ba9-875d-f310d3694845","SQL2019Arc","Microsoft.SqlVirtualMachine/sqlVirtualMachines","VM running","PAYG","ajayj","westus2" diff --git a/samples/manage/azure-hybrid-benefit/modify-license-type/Paygo-SQLArc.json b/samples/manage/azure-hybrid-benefit/modify-license-type/Paygo-SQLArc.json new file mode 100644 index 0000000000000000000000000000000000000000..75476a49c18072f809740fded62c254c5088a23d GIT binary patch literal 10994 zcmeHNTW=dh6h6;L{D){kN)XM(iDRdI!n6@Y3QeG)2%D$9GFJ#+52nScKNOFoy+WC_1ax^gNbxs-vlY$(@8#r&_sxF)I0`FJxW)r^+T-D?u?wYu( z%N~ssVTMYTMDZ1&YWw9(O=j6Tb%T>-aYuU8ZSo1C2R@T)W`E$#oArTyC^&F4~a)oPydOXo=j<;VXPcVjd zaseIN!#q!MHI`lAObZ&j?{llL?|A079Mgu*4cx5R)Ep-sf9zXYCuwQ}zX4{*aW%f( z4X4c6c$pRESkPMOC(N?Ru|vq=0{oyn_&n#|xx;o4p+|Yq1}8@N;w5B$=)OO5+~G6& z4Uo3gpz2HKS0g*NBY@RO5~!7X~^ai-L zAZKDtil2cq0~~2p*X~%1KK{HJWKg7FF??JHcBYB*;!GPf-$QwF)pC|van77kMsioWO^rW+57GYJ->1}5J zoPjqMF~fRwHueT1?(g$RN)N@{krYvL%DfNZ7UgVn`Dex_s}-zD#letODk)Q4Z4f|Q@DqRsST znisKa#Otb>o5`2RXqdP2d+YvWxThUl;@u-;^2~wqF>7ulEs|Dmer65#e?orDGS)Df z)j{|jYXbIT*q>lOh8-Z@ts~#hD|v%=x8LJ3BL6s`yBqYo2~Gj{Sv~ zkuCyz)dG|LUHn%Z??rO`ef`z^FrMX`I7<~x%A9AQ1=B~c+OS^3aWs=7T>n?iNAnBX z*Cp&cZt>a?-gG_FnmcY(@+XE%hI}gY@#E4U!{9Wd~Ykq2&+nIUhmFu~(`^uOz1n<><9lNTZy(Q}hj$Ca@-tA6xk`AZf+@3CC zl>v`f&PQopf!|iUrzBhE8Hp9EZ{~*6w1xfsV)n^zHQTMOBT7>-Hl#IkI&(KZmf5_? zw2JN9Smr6#wNj}sCL^vILCR=6f$Yl0X!R1xwrcjJ(weOWw}GYb!kXK9_GWDQ#x0X!RX2Q@_B~9$lw3s#@qt zGS?WsTaUTMNXt5`#=JuG)A+{-80W8Fn=*gpcy`>mDwnVOl<5W|;o^I`Tpi(hU7QkM z8u3d1zu4L38Xs3fdWb>l!CBF;nqVJ@D;l#py?*4lzYf4WyS{{Vf0U>M(tT>i$)(c1 zP|CJVL(4PF*owv{?WdJ+CBbr~k3svx7#jAiKMq?+#nrH1ZnlxKomfp0`iWFeFCHye zC30oI=XQ4x5_53Vtvy7)@~SaIM@cIdMql=p*!NkFt`D{lxwvk}{RpSXKJwVUJ`)qd zYhusPLv*w{*n88!Zkttix8u57byPW=nfsaaw~8lC^qaWPXcPZ!e8I8d?i%B_oj(*U zT)XF<67II*o~u>hxdr^VbBa5!xa)-!baBVpx$pLFHE@1`@jIZWjWJE+GcmnN<fr9?yh2u&kXb%mpRcM zuF-2fgQXEie`ksIi>tsda_nc!qJ4zWqp(jy492i~?rme1$-NmVj+E`A;|{tV@SrBM nIg*-n{=AtrQ<_U=pP^2UE7aw)e5J3`tcr@Bn_inUt4;h1q~ydZ literal 0 HcmV?d00001 diff --git a/samples/manage/azure-hybrid-benefit/modify-license-type/README.md b/samples/manage/azure-hybrid-benefit/modify-license-type/README.md index 53a369e3ac..e98b1dff7f 100644 --- a/samples/manage/azure-hybrid-benefit/modify-license-type/README.md +++ b/samples/manage/azure-hybrid-benefit/modify-license-type/README.md @@ -111,7 +111,7 @@ The script produces a report listing the affected resources by creating a `Modif - Location > [!NOTE] -> - If `-ReportOnly` is specified, the report shows the resources that would be affected without the actuall change being applied. +> - If `-ReportOnly` is specified, the report shows the resources that would be affected without the actual change being applied. # Script execution examples From be798c00e3e0a11b8a68e81efcdb039507a24f00 Mon Sep 17 00:00:00 2001 From: "Alexander (Sasha) Nosov" Date: Fri, 24 Oct 2025 16:15:31 -0700 Subject: [PATCH 2/2] renamed folder --- .../{monitor-compliance => compliance}/README.md | 0 .../arc-sql-payg-compliance/params.json | 0 .../arc-sql-payg-compliance/policy.json | 0 .../arc-sql-payg-compliance/rules.json | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename samples/manage/azure-arc-enabled-sql-server/{monitor-compliance => compliance}/README.md (100%) rename samples/manage/azure-arc-enabled-sql-server/{monitor-compliance => compliance}/arc-sql-payg-compliance/params.json (100%) rename samples/manage/azure-arc-enabled-sql-server/{monitor-compliance => compliance}/arc-sql-payg-compliance/policy.json (100%) rename samples/manage/azure-arc-enabled-sql-server/{monitor-compliance => compliance}/arc-sql-payg-compliance/rules.json (100%) diff --git a/samples/manage/azure-arc-enabled-sql-server/monitor-compliance/README.md b/samples/manage/azure-arc-enabled-sql-server/compliance/README.md similarity index 100% rename from samples/manage/azure-arc-enabled-sql-server/monitor-compliance/README.md rename to samples/manage/azure-arc-enabled-sql-server/compliance/README.md diff --git a/samples/manage/azure-arc-enabled-sql-server/monitor-compliance/arc-sql-payg-compliance/params.json b/samples/manage/azure-arc-enabled-sql-server/compliance/arc-sql-payg-compliance/params.json similarity index 100% rename from samples/manage/azure-arc-enabled-sql-server/monitor-compliance/arc-sql-payg-compliance/params.json rename to samples/manage/azure-arc-enabled-sql-server/compliance/arc-sql-payg-compliance/params.json diff --git a/samples/manage/azure-arc-enabled-sql-server/monitor-compliance/arc-sql-payg-compliance/policy.json b/samples/manage/azure-arc-enabled-sql-server/compliance/arc-sql-payg-compliance/policy.json similarity index 100% rename from samples/manage/azure-arc-enabled-sql-server/monitor-compliance/arc-sql-payg-compliance/policy.json rename to samples/manage/azure-arc-enabled-sql-server/compliance/arc-sql-payg-compliance/policy.json diff --git a/samples/manage/azure-arc-enabled-sql-server/monitor-compliance/arc-sql-payg-compliance/rules.json b/samples/manage/azure-arc-enabled-sql-server/compliance/arc-sql-payg-compliance/rules.json similarity index 100% rename from samples/manage/azure-arc-enabled-sql-server/monitor-compliance/arc-sql-payg-compliance/rules.json rename to samples/manage/azure-arc-enabled-sql-server/compliance/arc-sql-payg-compliance/rules.json