The Adventure of Automating Azure Security Center Part 1
Published Feb 12 2020 06:44 AM 10.4K Views



I hope this finds you well. I wanted to start a series of automating on Azure Security Center. The goal of this first article is to dive and walk through explaining and implementing a simple use case explaining Azure Security Center Workflow Automation which is now in Public Preview. Subsequent articles will dive deeper with more complex automation scenarios in mind. This article is for any person interested in automating Security within Azure but has not been involved or involved a little on Azure platform and Azure Security Center


If you would like to deploy the Key Vault auditing remediation use case directly please click here:


Two Pillars of Azure Security Center


Let's begin at a high level at it's core Azure Security Center offer two pillars of protection against your Azure cloud environment. Workflow automation scenarios can be designed against these two pillars. The first pillar is Cloud Security Posture Management (CSPM). This basically entails whenever new services or resources are spun up in Azure a security score and recommendations being assigned. For example a person spins up a virtual machine with a public ip address on Azure but assigns very permissive security group rules exposing the VM to unnecessary risks. Azure Security Center will flag the VM for Recommendations and also assign a security score to your overall security posture. To learn more about Azure Security Center Recommendations please check the end of article for reference links. (*1)


The 2nd pillar which will be out of scope for this initial article but we will return to in later articles is Cloud Workload Protection Platform (CWPP). This is basically threat detection capabilities on IaaS and PaaS resources in the cloud (*2). One example could be Possible SQL injection from the web/app tier into a PaaS SQL database running in Azure.


In our workflow automation scenario today we will look at newly created resource a Azure Key Vault that is deployed with less than ideal postures on Azure and using workflow automation to automatically solve the "Diagnostic Logs in KeyVault should be enabled" recommendation that fires. We will automate within Logic Apps calling a Generic Azure Resource Manager Template passing in unique parameters within the recommendation.


To do this we will need:


  1. Logic App
  2. Azure Security Center - Free Tier enabled
  3. Log Analytics Workspace
  4. Azure Resource Manager Template


1. Azure Logic App



To begin with we will need to create a Azure Logic App. Think of a Logic App as a way to do low code or no code solution designing against an array of services both inside and outside of Azure. If you're familiar with Microsoft Workflows in Office 365 or IF Then Then That ( same thing but running on Azure platform. The beauty of using Logic Apps is we can trigger automatically off of Azure Security Center recommendations or threat detection, without having to write complex rules. In addition we don't have to code out a solution in a programming language like python, bash, or PowerShell.


Logic Apps and the designer and code view take a bit to learn so we will be diving deep step by step how to do this so you can follow along.


Create the Logic App in the Azure Portal.









Once the Logic App is created go to the resource we will implement the Trigger portion to get started.




You will be taken to a default Logic App Designer page with some prebuilt templates to choose from scroll down just a bit and choose a blank Logic App, also not towards the very bottom there are some Azure Security Center logic apps to email you when a new recommendation occurs or threat is detected, very useful. In a separate blog article we will expand on the ASC recommendation to send to Tagged Owners of Resources so the security team doesn't have to hunt down and communicate to folks every time.




Once selected we are brought to a blank canvas and we can can create to our hearts desire automation workflow. To get started we need to define a trigger, since this will be from a Azure Security Center Recommendation we will start typing Azure Security Center and choose "When an Azure Security Center Recommendation is created or triggered"





! Be sure to save the Logic App in top left


Before we proceed further on defining the Logic App we need to create a few more things to aide in the auto remediation and also testing.


2. Azure Security Center - Workflow Automation


With a recent feature capability "Workflow Automation" we can now automate recommendations and threat detections. In fact this has been a huge ask over the years and it is great to see this capability in a easy to use format. Prior to this capability you could only run a Logic App Security Playbook manually off of a threat detection in the Portal.




Within Azure Security Center we will navigate to the new blade Workflow Automation




Lets get the glue in place for a specific Azure Security Center Recommendation: "Diagnostic Logs in KeyVault should be enabled" to automatically trigger the Logic App we just created. Choose the + Add workflow automation and we will begin setting up the details for the automatic trigger








Ensure the Logic App you are selecting has the Azure Security Center Trigger saved in the design template, it will show as (Security Center Recommendations connector), if it doesn't ensure the Logic App was saved with the Azure Security Center Connector for recommendations, and refresh the list in the workflow automation picker.


You can start to get a feel for the automation potential here, send an alert on any type or certain types of recommendations to a JIRA as a work item. DevOps can rebuild their Infrastructure templates to incorporate the recommendation so they never fire again during build and deploy time on Azure. You could send a recommendation onto the Azure Resource owner who just deployed, reminding them to fix this increase security score and prevent insecure posture. Or maybe an email / teams chat to the Cloud Governance team when Azure Resources become healthy from a posture perspective.


Go ahead and hit the create button to generate the glue between specific ASC alerts and a Logic App.




Now that this is setup lets test Workflow Automation and triggering the Logic App. This way we will have something we can test against as we further define the Logic App actions to auto remeditae.


Create a KeyVault in the Azure Portal.




Once deployed you will notice that the KeyVault that was deployed without the audit logs turned on or set to a log analytics workspace.




Within Azure Security Center, posture management pillar has found a new recommendation and updated our Azure Security Score. We may need to wait a few minutes for Azure Security Center to update recommendations on the newly create Resource. ASC typically runs hourly to update the security resource health, recommendations, and security score.








In addition if the workflow automation and logic app are correct we should see a successful trigger on the logic app history.








 The outputs produced by the recommendation and the Azure Security Center trigger are awesome, anything in here could be used and passed down to a Action we want to take in the Logic App on a different connector. In fact as you implement other triggers those results and outputs can be passed further down.


Before we go to much further into the Logic App design, we still have one more requisite we must create or identify and that is the Log Analytics workspace.


3. Log Analytics Workspace


How should I choose my workspace or create one order by importance.


  1. Existing Azure Sentinel connected workspace
  2. Create a new workspace if one does not exist attach Sentinel
  3. Existing Azure Security Center workspace


If you are using Azure Sentinel today it will have a workspace attached to it, the workspace will have a solution called Security Insights.





I choose Sentinel connected workspace first and foremost because there a myriad of detections available from the Audit and diagnostic logs Azure resources are feeding into them. For KeyVault as of this writing there are three interesting detections that can be setup in Azure Sentinel (*3).


If you don't have Sentinel now might be a good time to create a Log analytics workspace and enable one for this workflow - automation in Azure Security Center we are building.


Finally if you have no desire to use Azure Sentinel a cloud native SIEM and SOAR tool and the detections written for the Audit logs. Then send the Key Vault audit logs for compliance and searching needs then to a workspace defined by Azure Security Center or create a unique log analytics workspace.


Within Security Center you can check






If in doubt in the top search bar you can also search for SecurityCenter to see what log analytic workspaces are enabled and set with Azure Security Center.




Ultimately once you have identified the workspace that the KeyVault audit logs will go to or just created a new log analytics workspace and attached to Azure Sentinel you will have two more steps. The first we want to do is bring in a Log analytics Solution called Key Vault analytics - there is no charge for this and it will add some nice workbooks \ dashboards we can visualize and summarize the KeyVault operations that are occurring in the Audit logs. The Key Vault analytics can be found in the Azure Marketplace and you select the log analytics workspace they will be deployed to.





One last thing we need is the Resource ID of the Log analytics workspace. An easy way to find this is the azure portal navigate to the log analytics workspace




Copy and paste after the /Subscriptions/ in the URL browser. The resource ID should look like:




Paste it off in a notepad somewhere we will be using this log analytics workspace resource Id again later.


We are entering the home stretch we need to go back to the Logic App and further configure some actions.


Azure Logic App revisited


Within the the Logic App designer we will need to create a Action off the Azure Security Center recommendations trigger.






Our next step in the Logic App will be to use the Azure Resource Manager connector and the action of "Create or Update a template deployment" Check out the following reference for a exhaustive list of connectors and their definitions (*4).





When using a new connector a api and secure stored creds is created under the hood and can be seen within the resource group of the logic App. Here you can choose to sign in or use a a AAD Service Principal. I would recommend creating a service principal with limited RBAC to the subscription. Whatever is being used here will be used in the remediation efforts and will show in Azure Subscription Activity Logs (Who does what, when, against the Azure APIs). Basically audit logs.





Now we need to use some of the cool Logic App magic dynamic content and expressions to solve for passing values into these Logic App parameters that need to be answered to deploy correctly. In some cases you can statically assign or define static strings in the logic app connector. but in many cases like this one we don't know which keyvault across the subscriptions will be deployed, hence we will re use the outputs from the ASC Connector above to answer for us each time.


Some observations with the Logic Apps UI. You will sometimes see pickers with static lists, no worry if you start typing in the field you will get a Enter custom value prompt. Again we want to avoid static values as these could change on each insecure resource health.




Of particular note is the Dynamic Content "Properties Resource Details Id" as this will be unique resource id of each Azure KeyVault when this recommendation fires.




an example of : "Properties Resource Details Id" - remember the logic app run history output has this:





we can't just pass the entire string from the Dynamic Content "Properties Resource Details Id" into each of the Logic App parameters. We will need to manipulate that value further, thankfully Logic Apps not only has Dynamic Content generated by the connectors being used but also built in expressions or function to manipulate data further with little code.


We have Azure Resource Id and because the Id is split in unique sections we will use the expression split. To define this we need switch to expressions and start typing split




We can see in the notes of this expression we need to pass in a string (Dynamic Content -Properties Resource Details Id ) and the separator value to split on or in this case "/"




Switch back to dynamic content and choose the Properties Resource Details Id





Scroll all the way to the left in the field and we still need to add the separator , '/'


Once done be sure to copy the entire string and click the ok button




Once you click ok you should see the split expression in the Subscription parameter field, if you click on it or hover over it you will see the full expression




We will do the same for the Resource group parameter field clicking in it and choosing custom value, and then selecting expressions and copying and pasting what we had and pressing OK.





We will want to also add a unique guid for the deployment name, again we can click in the field and choose expression and guid()


One other item to switch is the Wait for Deployment No to Yes





We are now ready to add two more parameters to the Azure Resource manager template deployment.




We will add the Template URI and the Parameters we will pass into the template.




Now the Template URI is referring to a Azure Resource manager Template \ infrastructure as code. The templates are written in declarative JSON and many examples can be found in Azure Quickstart Templates (*5)


In our case rather than scour the internet, github searching, or writing from scratch, ughhhh. our good friends in Azure Security Center have tipped us a great way to do this. Recall that the Azure Security Center recommendation had a quick fix for this, it is a manual process but a simple click of button and filling out a few parameters. We are going to take that and post on a public URI to point to or reuse an existing one cleaned up here: KVAudit.json


To get from Azure Security Center recommendations Quick Fix you can go to Azure Secuirty Center - Recommendations - Identity& Access - Keyvault - the keyvault we created earlier - at bottom of recommendation click it - ajd under Remediation Steps click - View remediation logic. *Note you will have to trim the JSON a bit, see KVAudit.json and compare as source / example reference.





With the Azure Resource Manager Template URI we can now plug that in




Now we need to do the Azure Resource Template Parameters this can be either JObject or JSON string. I choose a JSON object as this is similar to the parameters.json examples out on github or azure quickstart templates.




The following code can be used for Parameters:


  "logAnalytics": {
    "value": "/subscriptions/{subscriptionID}/resourceGroups/{}resourceGroupName/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}"
  "resourceName": {
    "value": ""
  "retentionDays": {
    "value": "30"



Recall we saved the Log analytics workspace resourceID awhile ago in notepad, were using it here, if you didn't simply navigate to the Log analytics workspace overview page and copy the URL from /subscriptions/....


What about the resourceName in the parameters that can't be null, you are absolutely right, we need to use that fancy expression split() and dynamic content Properties Resource Details Id


Remember to click in between the "" in Parameters and switch to Expressions split() and then within () switch to dynamic content and choose Properties Resource Details Id and finish with a , '/'




Don't forget to hit OK to enter it in, it should now look like




we are good right ? You might have been asking yourself well we split the resourceID but we never declared where on the split to use for SubscriptionID, ResourceGroupName and ResourceName itself for the KeyVault and you are right we didn't we only did a split(). While searching up and down the Internet and testing I found one way to obtain the which indexed split to use by wrapping a split expression in a add length expression in another one split expression, I have also seen some online examples of using first or last expression potentially.


split(triggerBody()?['properties']?['resourceDetails']?['id'], '/')[add(length(split(triggerBody()?['properties']?['resourceDetails']?['id'], '/')), -1)]


Notice the last comma and negative number , -1 | this tells whick index working backwards on the resourceID to choose from. So -1 chooses the last / which is the keyvault resourcename


So we can redeploy this new expression one of two ways in Logic Apps let's explore both methods.


simply click the expression split(...) in the Parameters field resourceName: Value


once clicked it will put up the expression used simply copy from snippet above and replace




Be sure to click the Update button before leaving, this has already got me a few times.




What about the other two split expressions at the beginning of the Azure Resource Template deployment logic app action




We can also change expressions in code view, I know I know we said no code but this is low code portion, again to just get familiar with the Designer UI and options available to author these.


If you haven't yet please save the logic app in the top left corner




Back at the Logic App overview page and blades we are going to got o the blade Logic app code view, ah this is where the sausage gets made or at least all the choices \ logic app as code id revealed.





We can already see the change we made earlier in the Parameters field, go ahead and copy after the "@{ starting with the split( until the last ] right before }"




recall that last area, -1)] when we go to replace paste later in the code be sure to update that index counter


You will find a method PU and then the next line will be the path, we will modify parts of the path by replacing\pasting from clipboard.




The new line of code should look with edits and replaces should look like:


"path": "/subscriptions/@{encodeURIComponent(split(triggerBody()?['properties']?['resourceDetails']?['id'], '/')[add(length(split(triggerBody()?['properties']?['resourceDetails']?['id'], '/')), -7)])}/resourcegroups/@{encodeURIComponent(split(triggerBody()?['properties']?['resourceDetails']?['id'], '/')[add(length(split(triggerBody()?['properties']?['resourceDetails']?['id'], '/')), -5)])}/providers/Microsoft.Resources/deployments/@{encodeURIComponent(guid())}",



Once completed be sure to save in top left corner and if any expression or syntax is off this will fail the save. If having trouble switch back to the designer view and click on the expressions and change and update, be sure to replace -index# to where it needs to go -7 subscriptionId and -5 resourceGroupName


Our final Logic App should look like this, also spot check the expressions and Parameters field to ensure correctness.




No we can go back to the Logic App run history and use that sweet resubmit button to kick off the test. Also be sure refresh the runs history




If we got everything we should now have have a successful Logic App history if we didn't no fret we can investigate the errors and ensure the correct expressions applied.




In the resource group where the KeyVault was deployed we should see a successful deployment, if it failed, troubleshooting the failed resource template deployment may be needed to tweak the Logic app further.





In the resource group where the KeyVault was deployed we should see a successful deployment, if it failed, troubleshooting the failed resource template deployment may be needed to tweak the Logic app further.






We used Azure Security Center's newest feature workflow automation to remediate a recommendation for a Azure resource. This remediation is taken in the form of a Logic App to be triggered from the workflow automation and the Logic app itself calls a ARM template publicly hosted with new environment specifics or statically defined and passes in the parameters from the recommendation using Dynamic Content and Expressions. We can now start building other auto remediate capabilities out there around this pattern. NSG rules to permissive a new rule needs to be applied to restrict from Interment, WebApp or Storage configuration not secure ? Maybe you want to enable JIT every time a new VM comes online to take advantage of auditing and using specific access to management ports of that VM.


If you would like to deploy the remediation of Key Vault auditing click here:



This is just the beginning I should have another automation scenario out soon and hopefully a lighter walk through since we are now getting familiar with the capabilities on how to trigger and action on a Logic App and ASC.









Version history
Last update:
‎Oct 06 2021 01:30 PM
Updated by: