Hello readers!
In one of my recent post, Azure Monitor: Logs Ingestion API Tips & Tricks, I discussed some Tips and Tricks to better deal with the new Logs Ingestion API.
In this new one, I would like to share an example of how to use Managed Identities as authentication method for custom log ingestion, focusing only on the System Assigned Managed Identities. The Tutorial: Send data to Azure Monitor Logs with Logs ingestion API (Azure portal) documentation includes good samples for sending data that use Azure AD application but nothing that uses the managed identity.
Let me set a bit of context using a Q&A based approach.
Question #1: What do we need to have for using Managed Identity when uploading data to Azure Monitor with Log Ingestion API?
A:The answer is quite simple: we need to obtain a bearer token for the authentication; that is all we need. A simple but good explanation of what a bearer token is can be found at RFC 6750: OAuth 2.0 Bearer Token Usage.
Once we have the token, we can use the Invoke-RestMethod to authenticate against the https://monitor.azure.com//.default endpoint. All other information reported in the Generate sample data and Sample code pages, as well as the requirements for the data ingestion, remain required.
Question #2: Who validates the authentication request and release the authentication token?
A: Talking about Azure, we need to differentiate based on the request origin. If the authentication request is coming from An Azure VM or from an Arc-Enabled server, then it is Azure Instance Metadata Service responsibility to manage the request. Differently, if the request is coming from another resource type, say the Automation Account, it could be validated according to the RBAC definition. If the authentication request is contained inside a script, say an Automation Runbook that needs to connect to an SQL database, then the requested will be managed by the Identity Endpoint retrieved as environment variable for the given resource and pointed as $env:IDENTITY_ENDPOINT. For more information, see Using system-assigned managed identity to Access SQL Database.
Question #3: When and why do we need to authenticate using managed identities?
A: This one is simple as well: we could be in a situation where we are uploading data from an Azure VM or from an Arc-Enabled server or from an Automation runbook. In this case it is not ideal to use an App Registration. Why creating another security principal when we already have one, which is even more reliable and manageable?
Question #4: Is there any difference in using Managed Identities from Azure, Arc or Automation Runbook?
A: Not in how to use it, but in how the authentication is requested and used throughout the script.
Question #5: Should we assign managed identities permission on the target resource?
A: Of course, we should. Each and every access to a target resource is validated against the RBAC. This means that we must give enough permission to the managed identity on the target resource either using Azure built-in roles or by creating custom ones.
With that said, let me discuss and share some sample codes for the authentication for each of the three scenarios mentioned in Question #3
Azure VM or Azure Arc-Enabled server:
For more information about how to authenticate from VM using managed identity, see the article Use a Windows VM system-assigned managed identity to access Resource Manager. Below there’s sample code that sets the header and the uri to the right values and then uses the Invoke-RestMethod to retrieve the token object. Bear in mind that the token object contains different properties, but since we only need the token, we can directly point to the access_token properties while executing the Invoke-RestMethod. This code can be safely re-used.
## Obtain a bearer token for the system assigned managed identity
$header = @{Metadata=”true” };
$bearerToken = (Invoke-RestMethod -Uri $uri -Method “Get” -Headers $header).access_token
Azure Automation runbook:
For more information about authenticating access to azure resources from an automation runbook using a Managed Identity, see the Authenticate access with system-assigned managed identity and Generate an access token without using Azure cmdlets documentation. Below I am sharing a sample code that authenticates to Azure through the Automation Account managed identity and then retrieves the token. This code can be safely re-used.
# Connect to Azure with system-assigned managed identity
Connect-AzAccount -Identity | Out-Null
# Retrieving bearer token for the system-assigned managed identity
$bearerToken = (Get-AzAccessToken -ResourceUrl “https://monitor.azure.com//.default“).Token
Now that you know how to use the System Assigned Managed Identities to authenticate your Azure Monitor data ingestion, you can guess how a hypothetic sample code to send data from a virtual machine should look like. Something like this:
## Obtain a bearer token for the system assigned managed identity
$header = @{Metadata=”true” };
$bearerToken = (Invoke-RestMethod -Uri $uri -Method “Get” -Headers $header).access_token
<#
#### put your data retrieving and manipulation logic here
#>
# Sending the data to Log Analytics via DCR!
$body = $log_entry | ConvertTo-Json -AsArray;
$headers = @{“Authorization” = “Bearer $bearerToken”; “Content-Type” = “application/json” };
$uri = “$DceURI/dataCollectionRules/$DcrImmutableId/streams/Custom-$Table”+”?api-version=2021-11-01-preview”;
$uploadResponse = Invoke-RestMethod -Uri $uri -Method “Post” -Body $body -Headers $headers;
Thanks to my colleague @PerJub for his help on this approach.
Disclaimer
The sample scripts are not supported under any Microsoft standard support program or service. The sample scripts are provided AS IS without warranty of any kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Microsoft has been advised of the possibility of such damages.