diff --git a/azurerm/internal/services/sentinel/sentinel_alert_rule_scheduled_resource.go b/azurerm/internal/services/sentinel/sentinel_alert_rule_scheduled_resource.go index 45f860475996..cd0a5e126d2c 100644 --- a/azurerm/internal/services/sentinel/sentinel_alert_rule_scheduled_resource.go +++ b/azurerm/internal/services/sentinel/sentinel_alert_rule_scheduled_resource.go @@ -73,6 +73,24 @@ func resourceSentinelAlertRuleScheduled() *schema.Resource { ValidateFunc: validation.StringIsNotEmpty, }, + "event_grouping": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "aggregation_method": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + string(securityinsight.AlertPerResult), + string(securityinsight.SingleAlert), + }, false), + }, + }, + }, + }, + "tactics": { Type: schema.TypeSet, Optional: true, @@ -302,6 +320,10 @@ func resourceSentinelAlertRuleScheduledCreateUpdate(d *schema.ResourceData, meta param.ScheduledAlertRuleProperties.AlertRuleTemplateName = utils.String(v.(string)) } + if v, ok := d.GetOk("event_grouping"); ok { + param.ScheduledAlertRuleProperties.EventGroupingSettings = expandAlertRuleScheduledEventGroupingSetting(v.([]interface{})) + } + // Service avoid concurrent update of this resource via checking the "etag" to guarantee it is the same value as last Read. if !d.IsNewResource() { resp, err := client.Get(ctx, workspaceID.ResourceGroup, "Microsoft.OperationalInsights", workspaceID.WorkspaceName, name) @@ -380,6 +402,10 @@ func resourceSentinelAlertRuleScheduledRead(d *schema.ResourceData, meta interfa d.Set("suppression_enabled", prop.SuppressionEnabled) d.Set("suppression_duration", prop.SuppressionDuration) d.Set("alert_rule_template_guid", prop.AlertRuleTemplateName) + + if err := d.Set("event_grouping", flattenAlertRuleScheduledEventGroupingSetting(prop.EventGroupingSettings)); err != nil { + return fmt.Errorf("setting `event_grouping`: %+v", err) + } } return nil @@ -483,6 +509,21 @@ func expandAlertRuleScheduledGrouping(input []interface{}) *securityinsight.Grou return output } +func expandAlertRuleScheduledEventGroupingSetting(input []interface{}) *securityinsight.EventGroupingSettings { + if len(input) == 0 || input[0] == nil { + return nil + } + + v := input[0].(map[string]interface{}) + result := securityinsight.EventGroupingSettings{} + + if aggregationKind := v["aggregation_method"].(string); aggregationKind != "" { + result.AggregationKind = securityinsight.EventGroupingAggregationKind(aggregationKind) + } + + return &result +} + func flattenAlertRuleScheduledGrouping(input *securityinsight.GroupingConfiguration) []interface{} { if input == nil { return []interface{}{} @@ -520,3 +561,20 @@ func flattenAlertRuleScheduledGrouping(input *securityinsight.GroupingConfigurat }, } } + +func flattenAlertRuleScheduledEventGroupingSetting(input *securityinsight.EventGroupingSettings) []interface{} { + if input == nil { + return []interface{}{} + } + + var aggregationKind string + if input.AggregationKind != "" { + aggregationKind = string(input.AggregationKind) + } + + return []interface{}{ + map[string]interface{}{ + "aggregation_method": aggregationKind, + }, + } +} diff --git a/azurerm/internal/services/sentinel/sentinel_alert_rule_scheduled_resource_test.go b/azurerm/internal/services/sentinel/sentinel_alert_rule_scheduled_resource_test.go index 97d722db1cbd..d147fd3b97cc 100644 --- a/azurerm/internal/services/sentinel/sentinel_alert_rule_scheduled_resource_test.go +++ b/azurerm/internal/services/sentinel/sentinel_alert_rule_scheduled_resource_test.go @@ -107,6 +107,28 @@ func TestAccSentinelAlertRuleScheduled_withAlertRuleTemplateGuid(t *testing.T) { }) } +func TestAccSentinelAlertRuleScheduled_updateEventGroupingSetting(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_sentinel_alert_rule_scheduled", "test") + r := SentinelAlertRuleScheduledResource{} + + data.ResourceTest(t, r, []resource.TestStep{ + { + Config: r.eventGroupingSetting(data), + Check: resource.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + { + Config: r.updateEventGroupingSetting(data), + Check: resource.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + func (t SentinelAlertRuleScheduledResource) Exists(ctx context.Context, clients *clients.Client, state *terraform.InstanceState) (*bool, error) { id, err := parse.AlertRuleID(state.ID) if err != nil { @@ -217,6 +239,54 @@ QUERY `, r.template(data), data.RandomInteger) } +func (r SentinelAlertRuleScheduledResource) eventGroupingSetting(data acceptance.TestData) string { + return fmt.Sprintf(` +%s + +resource "azurerm_sentinel_alert_rule_scheduled" "test" { + name = "acctest-SentinelAlertRule-Sche-%d" + log_analytics_workspace_id = azurerm_log_analytics_workspace.test.id + display_name = "Some Rule" + severity = "Low" + alert_rule_template_guid = "65360bb0-8986-4ade-a89d-af3cf44d28aa" + query = <