Skip to content

Commit

Permalink
doc(README): updating documentation
Browse files Browse the repository at this point in the history
Added section on configuring managed system identity.

Added section on storing config file in blob storage.

Added section on setting role assignments to enable AAD access.
  • Loading branch information
veb3 committed Sep 27, 2021
1 parent e1698d4 commit 2f7d714
Showing 1 changed file with 46 additions and 14 deletions.
60 changes: 46 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Sending Azure Service Health Alerts to Teams Channels Using Azure Functions

The ASHWebhookToMessageCardFn.ps1 file contains code to use in a Powershell-based [Azure function](https://azure.microsoft.com/en-us/services/functions/) triggered by an incoming webhook (http trigger). *Azure Functions with Powershell runtimes are currently in Preview.*
The ASHWebhookToMessageCardFn.ps1 file contains code to use in a Powershell-based [Azure function](https://azure.microsoft.com/en-us/services/functions/) triggered by an incoming webhook (http trigger).

This code parses the payload of the incoming webhook and creates a [MessageCard](https://docs.microsoft.com/en-us/outlook/actionable-messages/message-card-reference) which is then sent as a webhook to a URI specified in an environment variable for the function.

Expand All @@ -10,21 +10,53 @@ While this code was built for use with Office365 Teams, the messageCard format i

## How to use this (simplified)

1. Create a Powershell function in Azure which uses a http (incoming webhook) trigger. **[This page](https://docs.microsoft.com/en-us/azure/azure-functions/functions-create-first-function-powershell)** is a good walkthrough of the process using [Visual Studio Code](https://code.visualstudio.com/). This will prepopulate the function with some skeleton Powershell code in a file named `run.ps1`.
2. Replace _all_ code in the `run.ps1` file with the contents of the ps1 file in this repository. No changes should be needed.
3. Create an **[Azure Service Health alert](https://docs.microsoft.com/en-us/azure/service-health/alerts-activity-log-service-notifications)** with an **[Action Group](https://docs.microsoft.com/en-us/azure/azure-monitor/platform/action-groups)** that sends a webhook to the trigger URI for the Azure function you created. ***The service health alert must be configured to use the [common alert schema](https://docs.microsoft.com/en-us/azure/azure-monitor/platform/alerts-common-schema) or you will get parse errors from the function when it runs.***
4. Get the trigger URI for your new function by clicking on "</> Get Function Url" on the screen which shows the function's code. The URL should look like `https://<yourfunctionname>.azurewebsites.net/api/...`
5. In Teams, **[create a Webhook Connector](https://docs.microsoft.com/en-us/microsoftteams/platform/concepts/connectors/connectors-using#setting-up-a-custom-incoming-webhook)** for the channel that should receive the alert notifications and make a note of the webhook URI.
6. Back in the Azure portal, create an application setting for your function named **webhookuri**. This is done using the **[Application settings](https://docs.microsoft.com/en-us/azure/azure-functions/functions-how-to-use-azure-function-app-settings#settings)** screen for the function with the **New application setting** button.
7. Create the following string as the value of the **webhookuri** Function App setting:
```
[{"channel":"<Name of Teams Channel>,"uri":"https://uri_of_teams_channel_webhook"}]
```
Application settings are visible to the function as environment variables.
8. Use a sample service health alert payload like the one at **[this link](https://docs.microsoft.com/en-us/azure/azure-monitor/platform/activity-log-alerts-webhook#servicehealth)** to trigger your function by calling the URI using curl or invoke-restmethod. This repository has a copy of the sample payload from this page in the file `SampleServiceHealthAlertWebhookPayload.json`. A message should appear in your Teams channel that looks like the screenshot at the bottom of this README. If the screenshot looks good in Teams then the function is working.
1. Create a Powershell function in Azure which uses a http (incoming webhook) trigger.
**[This page](https://docs.microsoft.com/en-us/azure/azure-functions/functions-create-first-function-powershell)** is a good walkthrough of the process using [Visual Studio Code](https://code.visualstudio.com/).
This will prepopulate the function with some skeleton Powershell code in a file named `run.ps1`.
2. Create a system managed identity for the Azure Function App to use.
Access the portal blade for your Function App.
On the left side under **Settings**, select **Identity**.
Toggle **Status** from **Off** to **On**.
See the following section on how to grant this identity access to the blob storage containing the configuration.
3. Replace _all_ code in the `run.ps1` file with the contents of `ASHWebhookToMessageCardFn.ps1` file in this repository.
No changes should be needed.
4. Create an **[Azure Service Health alert](https://docs.microsoft.com/en-us/azure/service-health/alerts-activity-log-service-notifications)** with an **[Action Group](https://docs.microsoft.com/en-us/azure/azure-monitor/platform/action-groups)** that sends a webhook to the trigger URI for the Azure function you created.
***The service health alert must be configured to use the [common alert schema](https://docs.microsoft.com/en-us/azure/azure-monitor/platform/alerts-common-schema) or you will get parse errors from the function when it runs.***
5. Get the trigger URI for your new function by clicking on "</> Get Function Url" on the screen which shows the function's code.
The URL should look like `https://<yourfunctionname>.azurewebsites.net/api/...`
6. In Teams, **[create a Webhook Connector](https://docs.microsoft.com/en-us/microsoftteams/platform/concepts/connectors/connectors-using#setting-up-a-custom-incoming-webhook)** for the channel that should receive the alert notifications and make a note of the webhook URI.
7. Follow the direction in the `./config` folder of this repository to configure the Azure Function App to use the generated webhook URI.
9. Use a sample service health alert payload like the one at **[this link](https://docs.microsoft.com/en-us/azure/azure-monitor/platform/activity-log-alerts-webhook#servicehealth)** to trigger your function by calling the URI using curl or invoke-restmethod.
This repository has a copy of the sample payload from this page in the file `SampleServiceHealthAlertWebhookPayload.json`.
A message should appear in your Teams channel that looks like the screenshot at the bottom of this README.
If the screenshot looks good in Teams then the function is working.
9. Wait for an Azure service health alert to trigger your function and check out the result!

The color of the bar at the top of the messageCard varies by the type of alert. In general, red indicates an urgent active issue, yellow indicates that action is needed, green indicates planned maintenance and blue indicates a message related to resolved or inactive alert such as a RCA posting. The MessageCard schema is fairly flexible and makes it easy to do things like add an icon to the card as well.
The color of the bar at the top of the messageCard varies by the type of alert.
In general, red indicates an urgent active issue, yellow indicates that action is needed, green indicates planned maintenance and blue indicates a message related to resolved or inactive alert such as a RCA posting.
The MessageCard schema is fairly flexible and makes it easy to do things like add an icon to the card as well.

![MessageCard Screenshot](https://github.com/KenHoover/AzureSHStuff/blob/master/SampleHealthAlertCard.PNG?raw=true "Sample MessageCard Output")

## Configure the Storage Account to Use AAD
```Powershell
$subscription = '{{ .nameOfSubscriptionContainingAzureFunctionApp }}'
$resourceGroup = '{{ .nameOfResourceGroupContainingStorageAccountforFunctionApp }}'
$storageAccountName = '{{ .nameOfStorageAccountUsedbyFunctionApp }}'
Set-AzContext -SubscriptionName $subscription
$scope = (Get-AzStorageAccount -Name $storageAccountName -ResourceGroupName $resourceGroup).Id
# get ObjectId of FunctionApp
$functionApp = '{{ .nameOfFunctionApp }}'
$managedSystemId = (Get-AzAdServicePrincipal -DisplayName $functionApp).objectId
$storageAccountRoles = @(
'Reader and Data Access'
'Storage Blob Data Contributor'
'Storage Account Key Operator Service Role'
)
$storageAccountRoles | % {New-AzRoleAssignment -RoleDefinitionName $_ -Scope $scope -ObjectId $managedSystemId}
```

0 comments on commit 2f7d714

Please sign in to comment.