We can use Azure DevOps to perform all the policy operations – Create and Assign Policy and Initiatives, Remediate non-compliant resources,
and check compliance status.
Steps to setup the environment for policy operations
Please refer the below Microsoft article for step-by-step process to setup the service connection.
Once we setup the service connection, we can get to see/update them as below-
We can update the name of pipeline, stage, Agent and Tasks as per our convenience.
Stage Name – Stage 1
Tasks – Create Azure Policy and Assign Azure Policy
Choose Azure Resource Manager as Azure Connection Type. If you have access to multiple Azure subscriptions linked through Service connection, you may choose any one of them and that will be used as scope for this policy assignment and creation.
Choose Script Type as Inline Script as we are providing the PowerShell script as inline content. We can use Script File Path as well in case we are using any repository like GitHub as the source for files.
$definition = New-AzPolicyDefinition -Name 'DenyCoolTier' -DisplayName 'DenyCoolTier' -Description
'Deny cool access tiering for storage' -Policy '{
"if": {
"allOf": [{
"field": "type",
"equals": "Microsoft.Storage/storageAccounts"
},
{
"field": "kind",
"equals": "BlobStorage"
},
{
"field": "Microsoft.Storage/storageAccounts/accessTier",
"equals": "cool"
}
]
},
"then": {
"effect": "deny"
}
}'
$definition = Get-AzPolicyDefinition | Where-Object { $_.Properties.DisplayName -eq 'DenyCoolTier'}
New-AzPolicyAssignment -Name "DenyCoolTier" -DisplayName "DenyCoolTier" -PolicyDefinition $definition
Once you click on create, you will get to see a message like in the below snippet that “Release has been created”.
It will start from Queued and will go into in Progress and then Succeeded. If there is some syntax or runtime error, the task will fail with Failed message. We can click on the status and see the error/failure reason.
If we click on Succeeded link in the Stage, you will get to see the status of each step that was performed by the agent and further we can click on the succeeded status of each step to see the operation logs(Refer below snippet).
Notes:
By default, the SPN created by Azure DevOps to connect to your Azure subscription is assigned the Contributor role. For updating the assignment of security roles on a resource group requires the Owner role. You need to ensure that the SPN used by Azure DevOps has the Owner role assigned at the subscription level. This is accomplished through the Access control (IAM) blade for the subscription –
Steps to Grant Azure AD permissions:
By default, the SPN created by Azure DevOps is only granted sign in and read user profile permissions against Azure AD. We now need to grant the SPN the additional read directory data permission.
a. Select API permission and then click on ‘Add a permission’
b. Select Azure Active Directory Graph from the list
c. Select Application permissions.
d. Select Directory.Read.All permission from the list and click on Add permissions.
e. Click on ‘Grant admin consent for Directory’.
Once permission is granted and the status shows as Green, Try running the deploying the Policy through Azure DevOps then.
In case of creating and assigning policy Initiatives, the above steps from 1-13 will remain the same except the sample code in steps 9 and 10. Please update the script as below:
Creating Policy Initiative: (Replace the code at Step 9)
$jsonPolicysetdefinition = @"
[ {
"policyDefinitionId": "/providers/Microsoft.Authorization/policyDefinitions/ea3f2387-9b95-492a-a190-fcdc54f7b070",
"parameters": {
"tagName": {
"value": "[parameters('tags')]"
}
}
},
{
"policyDefinitionId": "/providers/Microsoft.Authorization/policyDefinitions/a08ec900-254a-4555-9bf5-e42af04b5c5c",
"parameters": {
"listOfResourceTypesAllowed": {
"value": "[parameters('resourceTypes')]"
}
}
}
]"@
$jsonPolicydefinitionparameter = @"
{
"tags": {
"type": "String"
},
"resourceTypes": {
"type": "Array"
}
}"@
$Initiative= New-AzPolicySetDefinition -Name 'PolicyInitiativeTest' -PolicyDefinition $jsonPolicysetdefinition -Parameter $jsonPolicydefinitionparameter -SubscriptionId ‘abcd-e44e-4a99-a89c-45be63c6a8ad'
Write-Host $Initiative.PolicySetDefinitionId
Write-Host "##vso[task.setvariable variable=Initiative;isSecret=false;isOutput=true;]$Initiative.PolicySetDefinitionId"
Assign Policy Initiative: (Replace the code at Step 10)
$jsonPolicyassignmentparameter = @"
{
"tags": {
"value": "AnotherTag"
},
"resourceTypes": {
"value": [
"microsoft.devtestlab/labs/costs",
"microsoft.media/mediaservices/streamingpolicies",
"microsoft.security/iotsecuritysolutions/iotalerts",
"microsoft.security/iotsecuritysolutions/analyticsmodels/aggregatedrecommendations",
"microsoft.sql/managedinstances/metricdefinitions",
"microsoft.sql/managedinstances/databases/vulnerabilityassessments/rules/baselines",
"microsoft.sql/managedinstances/databases/backupshorttermretentionpolicies"
]
}
}"@
$Policy = Get-AzPolicySetDefinition -Name 'PolicyInitiativeTest'
$remediationID = New-AzPolicyAssignment -Name 'PolicyInitiativeAssignment' -Scope '/subscriptions/abcd-e44e-4a99-a89c-45be63c6a8ad' -PolicySetDefinition $Policy -PolicyParameter $jsonPolicyassignmentparameter -Location 'eastus' -AssignIdentity
$roleDefId = Get-AzRoleDefinition 'Contributor'
New-AzRoleAssignment -Scope '/subscriptions/abcd-e44e-4a99-a89c-45be63c6a8ad' -ObjectId $remediationID.Identity.PrincipalId -RoleDefinitionId $roleDefId.Id
for($i=0; $i -lt $initative.Properties.policyDefinitions.Length; $i++){
Start-AzPolicyRemediation -Name '$i Initiative' -PolicyAssignmentId $remediationID.PolicyAssignmentId -PolicyDefinitionReferenceId $initative.Properties.policyDefinitions[$i].policyDefinitionReferenceId }
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.