Introduction
In this post, I will walk you through the process of setting up a seamless integration between Azure Metric Alerts and Microsoft Teams. This integration allows you to receive real-time notifications in a Teams channel whenever an Azure metric alert is triggered.
Solution Components
To achieve this, I’ve designed a robust solution consisting of the following components:
- Azure Function App: The heart of the solution lies in an Azure Function App. This serverless compute service enables us to execute custom code in response to Azure Metric Alerts. By configuring the Function App as the trigger, we can seamlessly process alert data and initiate subsequent actions.
- Azure Storage Account: To store team member details who should get the @mention notification I used the Table storage feature.
- Azure Key Vault: Security is paramount, and I ensured that sensitive data such as API keys and authentication tokens remain protected. Utilizing Azure Key Vault, we securely store and access these credentials within the Function App.
- Microsoft Teams Webhook: To deliver alert messages to the Teams channel, I established a webhook integration. Teams webhooks facilitate seamless communication between Azure and Teams, ensuring that the right stakeholders receive critical alerts instantly.
- Azure Action Group: As part of the process, I set up an Azure Action Group. This group enables us to define the recipients and actions to be taken when the alert is triggered. By linking the Action Group to the Function App, we can effortlessly send notifications to the Teams channel.
Teams Webhook
- Go to the Microsoft Teams platform documentation: Microsoft Teams Webhooks.
- This link provides detailed instructions on how to set up an incoming webhook.
- Create a new incoming webhook in your desired Teams channel using the instructions from the provided link.
- Once the webhook is created, you’ll receive a unique URL. This URL is essential as it will be used to send alerts from the Azure Function App.
Azure Function App
- Function App Creation: The Function App has been successfully created using the Azure Portal. For cost efficiency, the function is set up as a Consumption-based plan, ensuring you pay only for the resources consumed during execution.
- Managed Identities Enabled: To bolster the security of the Function App and its interactions with other Azure services, Managed Identities have been enabled. This allows the Function App to authenticate itself automatically when accessing resources, such as fetching secrets from the Azure Key Vault.
By enabling Managed Identities, you eliminate the need for explicit authentication codes or credentials within your code, making the solution more secure and streamlined.
I used Visual Studio 2022 to create an Azure function from a template provided by Microsoft. I’ve shown images of how my solution explorer looks like and the installed NuGet packages.
The code for each of the files are included at this location: https://github.com/packet3/blogposts/tree/master/TeamsWebhookAzureFunction
I would like to mention the below code as this deals with fetching the needed secrets from Key vault and querying the azure storage table.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
var isDevelopment = string.Equals(Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"), "development", StringComparison.InvariantCultureIgnoreCase); if (isDevelopment) { client = new SecretClient(vaultUri: new Uri("https://mytestkeyvault.vault.azure.net"), credential: new VisualStudioCredential()); var storageConnectionKey = client.GetSecretAsync("AzureAlertsStorageAccount").Result; var teamsWebHook = client.GetSecretAsync("TeamsWebhook").Result; storageConnectionStringsecret = storageConnectionKey.Value.Value.ToString(); teamsWebHookSecret = teamsWebHook.Value.Value.ToString(); } else { var storageConnectionKey = System.Environment.GetEnvironmentVariable("AzureAlertStorageAccount"); var teamsWebHook = System.Environment.GetEnvironmentVariable("TeamsWebhook"); storageConnectionStringsecret = storageConnectionKey.ToString(); teamsWebHookSecret = teamsWebHook.ToString(); } var tableServiceClient = new TableServiceClient(storageConnectionStringsecret); var tableClient = tableServiceClient.GetTableClient("TeamContacts"); AsyncPageable<TeamContact> teamContacts = tableClient.QueryAsync<TeamContact>(); |
Azure Storage Account
- Azure Storage Account Setup: Using the Azure Portal, a Standard LRS (Locally Redundant Storage) account was successfully created. This storage account provides reliable and redundant data storage for our solution.
- Table Entity Creation: Within the storage account, a new Table entity named “TeamContacts” was created. This table will serve as a repository to store relevant contact information for the Teams integration.
- Sample Data Addition: For illustrative purposes in this article, sample data was added to the “TeamContacts” table. This data includes essential contact details, allowing us to demonstrate how the Azure Function interacts with the table to retrieve recipient information for the Teams notifications.
Azure Key vault
I created the Azure Key vault using the Azure Portal. Once created I then added my own user as a “Key Vault Administrator”, this is so that I am able to add Secrets. I created the following Secrets:
- AzureAlertsStorageAccount = This contained the connection string of the storage account.
- TeamsWebhook = This contained the Teams Webhook.
Function Permissions
Now that I have enabled managed identities on my function app, I can add the function app to the allowed list as shown below.
Function App – Key vault Reference
Now that my Key vault has the correct permissions for my Function App using managed identities , I can reference the secrets from the function App.
Using the Azure Portal I went back to my Function App resource and Added the following Configuration Values as shown below:
- AzureAlertStorageAccount = @Microsoft.KeyVault(SecretUri=https://mykeyvault.vault.azure.net/secrets/AzureAlertsStorageAccount/)
- TeamsWebhook = @Microsoft.KeyVault(SecretUri=https://mykeyvault.vault.azure.net/secrets/TeamsWebhook/)
Azure Action Group
with all the above created I could now create an action group to test. My action group didn’t have any data for the notifications section, but for the actions section I selected my azure function.
End result
After everything was in place the final result was as shown below.