diff --git a/azurerm/internal/services/sentinel/sentinel_alert_rule_ms_security_incident_resource.go b/azurerm/internal/services/sentinel/sentinel_alert_rule_ms_security_incident_resource.go index 9ce0be77af79..25ff849d1825 100644 --- a/azurerm/internal/services/sentinel/sentinel_alert_rule_ms_security_incident_resource.go +++ b/azurerm/internal/services/sentinel/sentinel_alert_rule_ms_security_incident_resource.go @@ -85,6 +85,13 @@ func resourceSentinelAlertRuleMsSecurityIncident() *schema.Resource { }, }, + "alert_rule_template_guid": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: validation.IsUUID, + }, + "description": { Type: schema.TypeString, Optional: true, @@ -109,6 +116,16 @@ func resourceSentinelAlertRuleMsSecurityIncident() *schema.Resource { }, }, + "display_name_exclude_filter": { + Type: schema.TypeSet, + Optional: true, + MinItems: 1, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringIsNotEmpty, + }, + }, + "text_whitelist": { Type: schema.TypeSet, Optional: true, @@ -161,12 +178,20 @@ func resourceSentinelAlertRuleMsSecurityIncidentCreateUpdate(d *schema.ResourceD }, } + if v, ok := d.GetOk("alert_rule_template_guid"); ok { + param.MicrosoftSecurityIncidentCreationAlertRuleProperties.AlertRuleTemplateName = utils.String(v.(string)) + } + if dnf, ok := d.GetOk("display_name_filter"); ok { param.DisplayNamesFilter = utils.ExpandStringSlice(dnf.(*schema.Set).List()) } else if dnf, ok := d.GetOk("text_whitelist"); ok { param.DisplayNamesFilter = utils.ExpandStringSlice(dnf.(*schema.Set).List()) } + if v, ok := d.GetOk("display_name_exclude_filter"); ok { + param.DisplayNamesExcludeFilter = utils.ExpandStringSlice(v.(*schema.Set).List()) + } + // 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) @@ -232,6 +257,7 @@ func resourceSentinelAlertRuleMsSecurityIncidentRead(d *schema.ResourceData, met d.Set("display_name", prop.DisplayName) d.Set("description", prop.Description) d.Set("enabled", prop.Enabled) + d.Set("alert_rule_template_guid", prop.AlertRuleTemplateName) if err := d.Set("text_whitelist", utils.FlattenStringSlice(prop.DisplayNamesFilter)); err != nil { return fmt.Errorf(`setting "text_whitelist": %+v`, err) @@ -239,6 +265,9 @@ func resourceSentinelAlertRuleMsSecurityIncidentRead(d *schema.ResourceData, met if err := d.Set("display_name_filter", utils.FlattenStringSlice(prop.DisplayNamesFilter)); err != nil { return fmt.Errorf(`setting "display_name_filter": %+v`, err) } + if err := d.Set("display_name_exclude_filter", utils.FlattenStringSlice(prop.DisplayNamesExcludeFilter)); err != nil { + return fmt.Errorf(`setting "display_name_exclude_filter": %+v`, err) + } if err := d.Set("severity_filter", flattenAlertRuleMsSecurityIncidentSeverityFilter(prop.SeveritiesFilter)); err != nil { return fmt.Errorf(`setting "severity_filter": %+v`, err) } diff --git a/azurerm/internal/services/sentinel/sentinel_alert_rule_ms_security_incident_resource_test.go b/azurerm/internal/services/sentinel/sentinel_alert_rule_ms_security_incident_resource_test.go index 44c19bd70565..fd42a41086ca 100644 --- a/azurerm/internal/services/sentinel/sentinel_alert_rule_ms_security_incident_resource_test.go +++ b/azurerm/internal/services/sentinel/sentinel_alert_rule_ms_security_incident_resource_test.go @@ -92,6 +92,50 @@ func TestAccSentinelAlertRuleMsSecurityIncident_requiresImport(t *testing.T) { }) } +func TestAccSentinelAlertRuleMsSecurityIncident_withAlertRuleTemplateGuid(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_sentinel_alert_rule_ms_security_incident", "test") + r := SentinelAlertRuleMsSecurityIncidentResource{} + + data.ResourceTest(t, r, []resource.TestStep{ + { + Config: r.alertRuleTemplateGuid(data), + Check: resource.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + +func TestAccSentinelAlertRuleMsSecurityIncident_withDisplayNameExcludeFilter(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_sentinel_alert_rule_ms_security_incident", "test") + r := SentinelAlertRuleMsSecurityIncidentResource{} + + data.ResourceTest(t, r, []resource.TestStep{ + { + Config: r.displayNameExcludeFilter(data, "alert3"), + Check: resource.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + { + Config: r.displayNameExcludeFilter(data, "alert4"), + 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 (t SentinelAlertRuleMsSecurityIncidentResource) Exists(ctx context.Context, clients *clients.Client, state *terraform.InstanceState) (*bool, error) { id, err := parse.SentinelAlertRuleID(state.ID) if err != nil { @@ -155,6 +199,37 @@ resource "azurerm_sentinel_alert_rule_ms_security_incident" "import" { `, r.basic(data)) } +func (r SentinelAlertRuleMsSecurityIncidentResource) alertRuleTemplateGuid(data acceptance.TestData) string { + return fmt.Sprintf(` +%s + +resource "azurerm_sentinel_alert_rule_ms_security_incident" "test" { + name = "acctest-SentinelAlertRule-MSI-%d" + log_analytics_workspace_id = azurerm_log_analytics_workspace.test.id + product_filter = "Microsoft Cloud App Security" + display_name = "some rule" + severity_filter = ["High"] + alert_rule_template_guid = "b3cfc7c0-092c-481c-a55b-34a3979758cb" +} +`, r.template(data), data.RandomInteger) +} + +func (r SentinelAlertRuleMsSecurityIncidentResource) displayNameExcludeFilter(data acceptance.TestData, displayNameExcludeFilter string) string { + return fmt.Sprintf(` +%s + +resource "azurerm_sentinel_alert_rule_ms_security_incident" "test" { + name = "acctest-SentinelAlertRule-MSI-%d" + log_analytics_workspace_id = azurerm_log_analytics_workspace.test.id + product_filter = "Microsoft Cloud App Security" + display_name = "some rule" + severity_filter = ["High"] + display_name_filter = ["alert1"] + display_name_exclude_filter = ["%s"] +} +`, r.template(data), data.RandomInteger, displayNameExcludeFilter) +} + func (SentinelAlertRuleMsSecurityIncidentResource) template(data acceptance.TestData) string { return fmt.Sprintf(` provider "azurerm" { diff --git a/website/docs/r/sentinel_alert_rule_ms_security_incident.html.markdown b/website/docs/r/sentinel_alert_rule_ms_security_incident.html.markdown index d2abd030b510..508d6ab4f4ac 100644 --- a/website/docs/r/sentinel_alert_rule_ms_security_incident.html.markdown +++ b/website/docs/r/sentinel_alert_rule_ms_security_incident.html.markdown @@ -56,12 +56,16 @@ The following arguments are supported: --- +* `alert_rule_template_guid` - (Optional) The GUID of the alert rule template which is used to create this Sentinel Scheduled Alert Rule. Changing this forces a new Sentinel MS Security Incident Alert Rule to be created. + * `description` - (Optional) The description of this Sentinel MS Security Incident Alert Rule. * `enabled` - (Optional) Should this Sentinel MS Security Incident Alert Rule be enabled? Defaults to `true`. * `display_name_filter` - (Optional) Only create incidents when the alert display name contain text from this list, leave empty to apply no filter. +* `display_name_exclude_filter` - (Optional) Only create incidents when the alert display name doesn't contain text from this list. + ## Attributes Reference In addition to the Arguments listed above - the following Attributes are exported: