Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for Secure Webhook Receiver in azurerm_monitor_action_group #10509

Merged
merged 10 commits into from
Mar 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 79 additions & 7 deletions azurerm/internal/services/monitor/monitor_action_group_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,35 @@ func resourceMonitorActionGroup() *schema.Resource {
Type: schema.TypeBool,
Optional: true,
},

"aad_auth": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"object_id": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.IsUUID,
},

"identifier_uri": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ValidateFunc: validation.IsURLWithScheme([]string{"api"}),
},

"tenant_id": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ValidateFunc: validation.IsUUID,
},
},
},
},
},
},
},
Expand Down Expand Up @@ -339,6 +368,7 @@ func resourceMonitorActionGroup() *schema.Resource {

func resourceMonitorActionGroupCreateUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).Monitor.ActionGroupsClient
tenantId := meta.(*clients.Client).Account.TenantId
ctx, cancel := timeouts.ForCreateUpdate(meta.(*clients.Client).StopContext, d)
defer cancel()

Expand Down Expand Up @@ -384,7 +414,7 @@ func resourceMonitorActionGroupCreateUpdate(d *schema.ResourceData, meta interfa
AzureAppPushReceivers: expandMonitorActionGroupAzureAppPushReceiver(azureAppPushReceiversRaw),
ItsmReceivers: expandMonitorActionGroupItsmReceiver(itsmReceiversRaw),
SmsReceivers: expandMonitorActionGroupSmsReceiver(smsReceiversRaw),
WebhookReceivers: expandMonitorActionGroupWebHookReceiver(webhookReceiversRaw),
WebhookReceivers: expandMonitorActionGroupWebHookReceiver(tenantId, webhookReceiversRaw),
AutomationRunbookReceivers: expandMonitorActionGroupAutomationRunbookReceiver(automationRunbookReceiversRaw),
VoiceReceivers: expandMonitorActionGroupVoiceReceiver(voiceReceiversRaw),
LogicAppReceivers: expandMonitorActionGroupLogicAppReceiver(logicAppReceiversRaw),
Expand Down Expand Up @@ -560,7 +590,7 @@ func expandMonitorActionGroupSmsReceiver(v []interface{}) *[]insights.SmsReceive
return &receivers
}

func expandMonitorActionGroupWebHookReceiver(v []interface{}) *[]insights.WebhookReceiver {
func expandMonitorActionGroupWebHookReceiver(tenantId string, v []interface{}) *[]insights.WebhookReceiver {
receivers := make([]insights.WebhookReceiver, 0)
for _, receiverValue := range v {
val := receiverValue.(map[string]interface{})
Expand All @@ -569,6 +599,17 @@ func expandMonitorActionGroupWebHookReceiver(v []interface{}) *[]insights.Webhoo
ServiceURI: utils.String(val["service_uri"].(string)),
UseCommonAlertSchema: utils.Bool(val["use_common_alert_schema"].(bool)),
}
if v, ok := val["aad_auth"].([]interface{}); ok && len(v) > 0 {
secureWebhook := v[0].(map[string]interface{})
receiver.UseAadAuth = utils.Bool(true)
receiver.ObjectID = utils.String(secureWebhook["object_id"].(string))
receiver.IdentifierURI = utils.String(secureWebhook["identifier_uri"].(string))
if v := secureWebhook["tenant_id"].(string); v != "" {
receiver.TenantID = utils.String(v)
} else {
receiver.TenantID = utils.String(tenantId)
}
}
receivers = append(receivers, receiver)
}
return &receivers
Expand Down Expand Up @@ -739,23 +780,54 @@ func flattenMonitorActionGroupWebHookReceiver(receivers *[]insights.WebhookRecei
result := make([]interface{}, 0)
if receivers != nil {
for _, receiver := range *receivers {
val := make(map[string]interface{})
var useCommonAlert bool
var name, serviceUri string
if receiver.Name != nil {
val["name"] = *receiver.Name
name = *receiver.Name
}
if receiver.ServiceURI != nil {
val["service_uri"] = *receiver.ServiceURI
serviceUri = *receiver.ServiceURI
}
if receiver.UseCommonAlertSchema != nil {
val["use_common_alert_schema"] = *receiver.UseCommonAlertSchema
useCommonAlert = *receiver.UseCommonAlertSchema
}

result = append(result, val)
result = append(result, map[string]interface{}{
"name": name,
"service_uri": serviceUri,
"use_common_alert_schema": useCommonAlert,
"aad_auth": flattenMonitorActionGroupSecureWebHookReceiver(receiver),
})
}
}
return result
}

func flattenMonitorActionGroupSecureWebHookReceiver(receiver insights.WebhookReceiver) []interface{} {
if receiver.UseAadAuth == nil || !*receiver.UseAadAuth {
return []interface{}{}
}

var objectId, identifierUri, tenantId string

if v := receiver.ObjectID; v != nil {
objectId = *v
}
if v := receiver.IdentifierURI; v != nil {
identifierUri = *v
}
if v := receiver.TenantID; v != nil {
tenantId = *v
}
return []interface{}{
map[string]interface{}{
"object_id": objectId,
"identifier_uri": identifierUri,
"tenant_id": tenantId,
},
}
}

func flattenMonitorActionGroupAutomationRunbookReceiver(receivers *[]insights.AutomationRunbookReceiver) []interface{} {
result := make([]interface{}, 0)
if receivers != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package monitor_test
import (
"context"
"fmt"
"os"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
Expand Down Expand Up @@ -125,6 +126,42 @@ func TestAccMonitorActionGroup_webhookReceiver(t *testing.T) {
})
}

func TestAccMonitorActionGroup_secureWebhookReceiver(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_monitor_action_group", "test")
r := MonitorActionGroupResource{}

data.ResourceTest(t, r, []resource.TestStep{
{
Config: r.basic(data),
Check: resource.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep(),
{
Config: r.webhookReceiver(data),
Check: resource.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep(),
{
Config: r.secureWebhookReceiver(data),
Check: resource.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep(),
{
Config: r.basic(data),
Check: resource.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep(),
})
}

func TestAccMonitorActionGroup_automationRunbookReceiver(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_monitor_action_group", "test")
r := MonitorActionGroupResource{}
Expand Down Expand Up @@ -511,6 +548,45 @@ resource "azurerm_monitor_action_group" "test" {
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger)
}

func (MonitorActionGroupResource) secureWebhookReceiver(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
features {}
}

resource "azurerm_resource_group" "test" {
name = "acctestRG-%d"
location = "%s"
}

data "azuread_application" "test" {
object_id = "%s"
}

resource "azurerm_monitor_action_group" "test" {
name = "acctestActionGroup-%d"
resource_group_name = azurerm_resource_group.test.name
short_name = "acctestag"

webhook_receiver {
name = "callmyapiaswell"
service_uri = "http://example.com/alert"
use_common_alert_schema = true
}

webhook_receiver {
name = "callmysecureapi"
service_uri = "http://secureExample.com/alert"
use_common_alert_schema = true
aad_auth {
object_id = data.azuread_application.test.object_id
identifier_uri = data.azuread_application.test.identifier_uris[0]
}
}
}
`, data.RandomInteger, data.Locations.Primary, os.Getenv("ARM_APP_OBJECT_ID"), data.RandomInteger)
}

func (MonitorActionGroupResource) automationRunbookReceiver(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
Expand Down
9 changes: 9 additions & 0 deletions website/docs/r/monitor_action_group.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,15 @@ The following arguments are supported:
* `name` - (Required) The name of the webhook receiver. Names must be unique (case-insensitive) across all receivers within an action group.
* `service_uri` - (Required) The URI where webhooks should be sent.
* `use_common_alert_schema` - (Optional) Enables or disables the common alert schema.
* `aad_auth` - (Optional) The `aad_auth` block as defined below

~> **NOTE:** Before adding a secure webhook receiver by setting `aad_auth`, please read [the configuration instruction of the AAD application](https://docs.microsoft.com/en-us/azure/azure-monitor/platform/action-groups#secure-webhook).

`aad_auth` supports the following:.

* `object_id` - (Required) The webhook application object Id for aad auth.
* `identifier_uri` - (Optional) The identifier uri for aad auth.
* `tenant_id` - (Optional) The tenant id for aad auth.

## Attributes Reference

Expand Down