diff --git a/azurerm/internal/services/monitor/action_rule.go b/azurerm/internal/services/monitor/action_rule.go index 55404189503e..3d2c22f3df58 100644 --- a/azurerm/internal/services/monitor/action_rule.go +++ b/azurerm/internal/services/monitor/action_rule.go @@ -2,7 +2,6 @@ package monitor import ( "github.com/hashicorp/terraform-plugin-sdk/helper/schema" - "github.com/hashicorp/terraform-plugin-sdk/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" "github.com/Azure/azure-sdk-for-go/services/preview/alertsmanagement/mgmt/2019-05-05/alertsmanagement" @@ -28,109 +27,7 @@ var weekDayMap = map[string]int{ "Saturday": 6, } -func schemaActionRuleAlertContextCondtion() *schema.Schema { - return schemaActionRuleCondtion( - validation.StringInSlice([]string{ - string(alertsmanagement.Equals), - string(alertsmanagement.NotEquals), - string(alertsmanagement.Contains), - string(alertsmanagement.DoesNotContain), - }, false), - validation.StringIsNotEmpty, - ) -} - -func schemaActionRuleAlertRuleIDCondtion() *schema.Schema { - return schemaActionRuleCondtion( - validation.StringInSlice([]string{ - string(alertsmanagement.Equals), - string(alertsmanagement.NotEquals), - string(alertsmanagement.Contains), - string(alertsmanagement.DoesNotContain), - }, false), - validation.StringIsNotEmpty, - ) -} - -func schemaActionRuleDescriptionCondtion() *schema.Schema { - return schemaActionRuleCondtion( - validation.StringInSlice([]string{ - string(alertsmanagement.Equals), - string(alertsmanagement.NotEquals), - string(alertsmanagement.Contains), - string(alertsmanagement.DoesNotContain), - }, false), - validation.StringIsNotEmpty, - ) -} - -func schemaActionRuleMonitorCondtion() *schema.Schema { - return schemaActionRuleCondtion( - validation.StringInSlice([]string{ - string(alertsmanagement.Equals), - string(alertsmanagement.NotEquals), - }, false), - validation.StringInSlice([]string{ - string(alertsmanagement.Fired), - string(alertsmanagement.Resolved), - }, false), - ) -} - -func schemaActionRuleMonitorServiceCondtion() *schema.Schema { - return schemaActionRuleCondtion( - validation.StringInSlice([]string{ - string(alertsmanagement.Equals), - string(alertsmanagement.NotEquals), - }, false), - // the supported type list is not consistent with the swagger and sdk - // https://github.com/Azure/azure-rest-api-specs/issues/9076 - // directly use string constant - validation.StringInSlice([]string{ - "ActivityLog Administrative", - "ActivityLog Autoscale", - "ActivityLog Policy", - "ActivityLog Recommendation", - "ActivityLog Security", - "Application Insights", - "Azure Backup", - "Data Box Edge", - "Data Box Gateway", - "Health Platform", - "Log Analytics", - "Platform", - "Resource Health", - }, false), - ) -} - -func schemaActionRuleSeverityCondtion() *schema.Schema { - return schemaActionRuleCondtion( - validation.StringInSlice([]string{ - string(alertsmanagement.Equals), - string(alertsmanagement.NotEquals), - }, false), - validation.StringInSlice([]string{ - string(alertsmanagement.Sev0), - string(alertsmanagement.Sev1), - string(alertsmanagement.Sev2), - string(alertsmanagement.Sev3), - string(alertsmanagement.Sev4), - }, false), - ) -} - -func schemaActionRuleTargetResourceTypeCondtion() *schema.Schema { - return schemaActionRuleCondtion( - validation.StringInSlice([]string{ - string(alertsmanagement.Equals), - string(alertsmanagement.NotEquals), - }, false), - validation.StringIsNotEmpty, - ) -} - -func schemaActionRuleCondtion(operatorValidateFunc, valuesValidateFunc schema.SchemaValidateFunc) *schema.Schema { +func schemaActionRuleCondition(operatorValidateFunc, valuesValidateFunc schema.SchemaValidateFunc) *schema.Schema { return &schema.Schema{ Type: schema.TypeList, Optional: true, @@ -168,6 +65,35 @@ func expandArmActionRuleCondition(input []interface{}) *alertsmanagement.Conditi } } +func expandArmActionRuleScope(input []interface{}) *alertsmanagement.Scope { + if len(input) == 0 { + return nil + } + + v := input[0].(map[string]interface{}) + return &alertsmanagement.Scope{ + ScopeType: alertsmanagement.ScopeType(v["type"].(string)), + Values: utils.ExpandStringSlice(v["resource_ids"].(*schema.Set).List()), + } +} + +func expandArmActionRuleConditions(input []interface{}) *alertsmanagement.Conditions { + if len(input) == 0 { + return nil + } + v := input[0].(map[string]interface{}) + + return &alertsmanagement.Conditions{ + AlertContext: expandArmActionRuleCondition(v["alert_context"].([]interface{})), + AlertRuleID: expandArmActionRuleCondition(v["alert_rule_id"].([]interface{})), + Description: expandArmActionRuleCondition(v["description"].([]interface{})), + MonitorCondition: expandArmActionRuleCondition(v["monitor"].([]interface{})), + MonitorService: expandArmActionRuleCondition(v["monitor_service"].([]interface{})), + Severity: expandArmActionRuleCondition(v["severity"].([]interface{})), + TargetResourceType: expandArmActionRuleCondition(v["target_resource_type"].([]interface{})), + } +} + func flattenArmActionRuleCondition(input *alertsmanagement.Condition) []interface{} { if input == nil { return make([]interface{}, 0) @@ -184,3 +110,47 @@ func flattenArmActionRuleCondition(input *alertsmanagement.Condition) []interfac }, } } + +func flattenArmActionRuleScope(input *alertsmanagement.Scope) []interface{} { + if input == nil { + return make([]interface{}, 0) + } + + var scopeType alertsmanagement.ScopeType + if input.ScopeType != "" { + scopeType = input.ScopeType + } + return []interface{}{ + map[string]interface{}{ + "type": scopeType, + "resource_ids": utils.FlattenStringSlice(input.Values), + }, + } +} + +func flattenArmActionRuleConditions(input *alertsmanagement.Conditions) []interface{} { + if input == nil { + return make([]interface{}, 0) + } + return []interface{}{ + map[string]interface{}{ + "alert_context": flattenArmActionRuleCondition(input.AlertContext), + "alert_rule_id": flattenArmActionRuleCondition(input.AlertRuleID), + "description": flattenArmActionRuleCondition(input.Description), + "monitor": flattenArmActionRuleCondition(input.MonitorCondition), + "monitor_service": flattenArmActionRuleCondition(input.MonitorService), + "severity": flattenArmActionRuleCondition(input.Severity), + "target_resource_type": flattenArmActionRuleCondition(input.TargetResourceType), + }, + } +} + +func FlattenInt32Slice(input *[]int32) []interface{} { + result := make([]interface{}, 0) + if input != nil { + for _, item := range *input { + result = append(result, item) + } + } + return result +} diff --git a/azurerm/internal/services/monitor/monitor_action_rule_action_group_resource.go b/azurerm/internal/services/monitor/monitor_action_rule_action_group_resource.go new file mode 100644 index 000000000000..89873b4e11c1 --- /dev/null +++ b/azurerm/internal/services/monitor/monitor_action_rule_action_group_resource.go @@ -0,0 +1,306 @@ +package monitor + +import ( + "fmt" + "log" + "time" + + "github.com/Azure/azure-sdk-for-go/services/preview/alertsmanagement/mgmt/2019-05-05/alertsmanagement" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/location" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/monitor/parse" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/monitor/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + azSchema "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tf/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmMonitorActionRuleActionGroup() *schema.Resource { + return &schema.Resource{ + Create: resourceArmMonitorActionRuleActionGroupCreateUpdate, + Read: resourceArmMonitorActionRuleActionGroupRead, + Update: resourceArmMonitorActionRuleActionGroupCreateUpdate, + Delete: resourceArmMonitorActionRuleActionGroupDelete, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(30 * time.Minute), + Read: schema.DefaultTimeout(5 * time.Minute), + Update: schema.DefaultTimeout(30 * time.Minute), + Delete: schema.DefaultTimeout(30 * time.Minute), + }, + + Importer: azSchema.ValidateResourceIDPriorToImport(func(id string) error { + _, err := parse.ActionRuleID(id) + return err + }), + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.ActionRuleName, + }, + + "resource_group_name": azure.SchemaResourceGroupName(), + + "action_group_id": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.ActionGroupID, + }, + + "description": { + Type: schema.TypeString, + Optional: true, + }, + + "enabled": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + + "condition": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "alert_context": schemaActionRuleCondition( + validation.StringInSlice([]string{ + string(alertsmanagement.Equals), + string(alertsmanagement.NotEquals), + string(alertsmanagement.Contains), + string(alertsmanagement.DoesNotContain), + }, false), + validation.StringIsNotEmpty, + ), + + "alert_rule_id": schemaActionRuleCondition( + validation.StringInSlice([]string{ + string(alertsmanagement.Equals), + string(alertsmanagement.NotEquals), + string(alertsmanagement.Contains), + string(alertsmanagement.DoesNotContain), + }, false), + validation.StringIsNotEmpty, + ), + + "description": schemaActionRuleCondition( + validation.StringInSlice([]string{ + string(alertsmanagement.Equals), + string(alertsmanagement.NotEquals), + string(alertsmanagement.Contains), + string(alertsmanagement.DoesNotContain), + }, false), + validation.StringIsNotEmpty, + ), + + "monitor": schemaActionRuleCondition( + validation.StringInSlice([]string{ + string(alertsmanagement.Equals), + string(alertsmanagement.NotEquals), + }, false), + validation.StringInSlice([]string{ + string(alertsmanagement.Fired), + string(alertsmanagement.Resolved), + }, false), + ), + + "monitor_service": schemaActionRuleCondition( + validation.StringInSlice([]string{ + string(alertsmanagement.Equals), + string(alertsmanagement.NotEquals), + }, false), + // the supported type list is not consistent with the swagger and sdk + // https://github.com/Azure/azure-rest-api-specs/issues/9076 + // directly use string constant + validation.StringInSlice([]string{ + "ActivityLog Administrative", + "ActivityLog Autoscale", + "ActivityLog Policy", + "ActivityLog Recommendation", + "ActivityLog Security", + "Application Insights", + "Azure Backup", + "Data Box Edge", + "Data Box Gateway", + "Health Platform", + "Log Analytics", + "Platform", + "Resource Health", + }, false), + ), + + "severity": schemaActionRuleCondition( + validation.StringInSlice([]string{ + string(alertsmanagement.Equals), + string(alertsmanagement.NotEquals), + }, false), + validation.StringInSlice([]string{ + string(alertsmanagement.Sev0), + string(alertsmanagement.Sev1), + string(alertsmanagement.Sev2), + string(alertsmanagement.Sev3), + string(alertsmanagement.Sev4), + }, false), + ), + + "target_resource_type": schemaActionRuleCondition( + validation.StringInSlice([]string{ + string(alertsmanagement.Equals), + string(alertsmanagement.NotEquals), + }, false), + validation.StringIsNotEmpty, + ), + }, + }, + }, + + "scope": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + string(alertsmanagement.ScopeTypeResourceGroup), + string(alertsmanagement.ScopeTypeResource), + }, false), + }, + + "resource_ids": { + Type: schema.TypeSet, + Required: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: azure.ValidateResourceID, + }, + }, + }, + }, + }, + + "tags": tags.Schema(), + }, + } +} + +func resourceArmMonitorActionRuleActionGroupCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).Monitor.ActionRulesClient + ctx, cancel := timeouts.ForCreateUpdate(meta.(*clients.Client).StopContext, d) + defer cancel() + + resourceGroup := d.Get("resource_group_name").(string) + name := d.Get("name").(string) + + if d.IsNewResource() { + existing, err := client.GetByName(ctx, resourceGroup, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("checking for presence of existing Monitor ActionRule %q (Resource Group %q): %+v", name, resourceGroup, err) + } + } + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_monitor_action_rule_action_group", *existing.ID) + } + } + + actionRuleStatus := alertsmanagement.Enabled + if !d.Get("enabled").(bool) { + actionRuleStatus = alertsmanagement.Disabled + } + + actionRule := alertsmanagement.ActionRule{ + // the location is always global from the portal + Location: utils.String(location.Normalize("Global")), + Properties: &alertsmanagement.ActionGroup{ + ActionGroupID: utils.String(d.Get("action_group_id").(string)), + Scope: expandArmActionRuleScope(d.Get("scope").([]interface{})), + Conditions: expandArmActionRuleConditions(d.Get("condition").([]interface{})), + Description: utils.String(d.Get("description").(string)), + Status: actionRuleStatus, + Type: alertsmanagement.TypeActionGroup, + }, + Tags: tags.Expand(d.Get("tags").(map[string]interface{})), + } + + if _, err := client.CreateUpdate(ctx, resourceGroup, name, actionRule); err != nil { + return fmt.Errorf("creating/updatinge Monitor ActionRule %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + resp, err := client.GetByName(ctx, resourceGroup, name) + if err != nil { + return fmt.Errorf("retrieving Monitor ActionRule %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if resp.ID == nil || *resp.ID == "" { + return fmt.Errorf("empty or nil ID returned for Monitor ActionRule %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + d.SetId(*resp.ID) + return resourceArmMonitorActionRuleActionGroupRead(d, meta) +} + +func resourceArmMonitorActionRuleActionGroupRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).Monitor.ActionRulesClient + ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) + defer cancel() + + id, err := parse.ActionRuleID(d.Id()) + if err != nil { + return err + } + + resp, err := client.GetByName(ctx, id.ResourceGroup, id.Name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[INFO] Action Rule %q does not exist - removing from state", d.Id()) + d.SetId("") + return nil + } + return fmt.Errorf("retrieving Monitor ActionRule %q (Resource Group %q): %+v", id.Name, id.ResourceGroup, err) + } + + d.Set("name", resp.Name) + d.Set("resource_group_name", id.ResourceGroup) + if resp.Properties != nil { + props, _ := resp.Properties.AsActionGroup() + d.Set("description", props.Description) + d.Set("action_group_id", props.ActionGroupID) + d.Set("enabled", props.Status == alertsmanagement.Enabled) + if err := d.Set("scope", flattenArmActionRuleScope(props.Scope)); err != nil { + return fmt.Errorf("setting scope: %+v", err) + } + if err := d.Set("condition", flattenArmActionRuleConditions(props.Conditions)); err != nil { + return fmt.Errorf("setting condition: %+v", err) + } + } + + return tags.FlattenAndSet(d, resp.Tags) +} + +func resourceArmMonitorActionRuleActionGroupDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).Monitor.ActionRulesClient + ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d) + defer cancel() + + id, err := parse.ActionRuleID(d.Id()) + if err != nil { + return err + } + + if _, err := client.Delete(ctx, id.ResourceGroup, id.Name); err != nil { + return fmt.Errorf("deleting monitor ActionRule %q (Resource Group %q): %+v", id.Name, id.ResourceGroup, err) + } + return nil +} diff --git a/azurerm/internal/services/monitor/resource_arm_monitor_action_rule.go b/azurerm/internal/services/monitor/monitor_action_rule_suppression_resource.go similarity index 59% rename from azurerm/internal/services/monitor/resource_arm_monitor_action_rule.go rename to azurerm/internal/services/monitor/monitor_action_rule_suppression_resource.go index c8d7ac249cc7..8c74f163ae9e 100644 --- a/azurerm/internal/services/monitor/resource_arm_monitor_action_rule.go +++ b/azurerm/internal/services/monitor/monitor_action_rule_suppression_resource.go @@ -20,12 +20,12 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) -func resourceArmMonitorActionRule() *schema.Resource { +func resourceArmMonitorActionRuleSuppression() *schema.Resource { return &schema.Resource{ - Create: resourceArmMonitorActionRuleCreateUpdate, - Read: resourceArmMonitorActionRuleRead, - Update: resourceArmMonitorActionRuleCreateUpdate, - Delete: resourceArmMonitorActionRuleDelete, + Create: resourceArmMonitorActionRuleSuppressionCreateUpdate, + Read: resourceArmMonitorActionRuleSuppressionRead, + Update: resourceArmMonitorActionRuleSuppressionCreateUpdate, + Delete: resourceArmMonitorActionRuleSuppressionDelete, Timeouts: &schema.ResourceTimeout{ Create: schema.DefaultTimeout(30 * time.Minute), @@ -49,67 +49,10 @@ func resourceArmMonitorActionRule() *schema.Resource { "resource_group_name": azure.SchemaResourceGroupName(), - "type": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validation.StringInSlice([]string{ - string(alertsmanagement.TypeActionGroup), - string(alertsmanagement.TypeDiagnostics), - string(alertsmanagement.TypeSuppression), - }, false), - }, - - "description": { - Type: schema.TypeString, - Optional: true, - }, - - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - - "scope": { + "suppression": { Type: schema.TypeList, - Optional: true, + Required: true, MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "type": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.StringInSlice([]string{ - string(alertsmanagement.ScopeTypeResourceGroup), - string(alertsmanagement.ScopeTypeResource), - }, false), - }, - - "resource_ids": { - Type: schema.TypeSet, - Required: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - ValidateFunc: azure.ValidateResourceID, - }, - }, - }, - }, - }, - - "action_group_id": { - Type: schema.TypeString, - Optional: true, - ValidateFunc: validate.ActionGroupID, - ConflictsWith: []string{"suppression"}, - }, - - "suppression": { - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - ConflictsWith: []string{"action_group_id"}, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "recurrence_type": { @@ -161,13 +104,14 @@ func resourceArmMonitorActionRule() *schema.Resource { ConflictsWith: []string{"suppression.0.schedule.0.recurrence_monthly"}, Elem: &schema.Schema{ Type: schema.TypeString, - ValidateFunc: validation.StringInSlice(weekDays, false), + ValidateFunc: validation.IsDayOfTheWeek(false), }, }, "recurrence_monthly": { Type: schema.TypeSet, Optional: true, + MinItems: 1, ConflictsWith: []string{"suppression.0.schedule.0.recurrence_weekly"}, Elem: &schema.Schema{ Type: schema.TypeInt, @@ -181,25 +125,137 @@ func resourceArmMonitorActionRule() *schema.Resource { }, }, - "condition": { + "description": { + Type: schema.TypeString, + Optional: true, + }, + + "enabled": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + + "scope": { Type: schema.TypeList, Optional: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "alert_context": schemaActionRuleAlertContextCondtion(), + "type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + string(alertsmanagement.ScopeTypeResourceGroup), + string(alertsmanagement.ScopeTypeResource), + }, false), + }, - "alert_rule_id": schemaActionRuleAlertRuleIDCondtion(), + "resource_ids": { + Type: schema.TypeSet, + Required: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: azure.ValidateResourceID, + }, + }, + }, + }, + }, - "description": schemaActionRuleDescriptionCondtion(), + "condition": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "alert_context": schemaActionRuleCondition( + validation.StringInSlice([]string{ + string(alertsmanagement.Equals), + string(alertsmanagement.NotEquals), + string(alertsmanagement.Contains), + string(alertsmanagement.DoesNotContain), + }, false), + validation.StringIsNotEmpty, + ), + + "alert_rule_id": schemaActionRuleCondition( + validation.StringInSlice([]string{ + string(alertsmanagement.Equals), + string(alertsmanagement.NotEquals), + string(alertsmanagement.Contains), + string(alertsmanagement.DoesNotContain), + }, false), + validation.StringIsNotEmpty, + ), + + "description": schemaActionRuleCondition( + validation.StringInSlice([]string{ + string(alertsmanagement.Equals), + string(alertsmanagement.NotEquals), + string(alertsmanagement.Contains), + string(alertsmanagement.DoesNotContain), + }, false), + validation.StringIsNotEmpty, + ), - "monitor": schemaActionRuleMonitorCondtion(), + "monitor": schemaActionRuleCondition( + validation.StringInSlice([]string{ + string(alertsmanagement.Equals), + string(alertsmanagement.NotEquals), + }, false), + validation.StringInSlice([]string{ + string(alertsmanagement.Fired), + string(alertsmanagement.Resolved), + }, false), + ), - "monitor_service": schemaActionRuleMonitorServiceCondtion(), + "monitor_service": schemaActionRuleCondition( + validation.StringInSlice([]string{ + string(alertsmanagement.Equals), + string(alertsmanagement.NotEquals), + }, false), + // the supported type list is not consistent with the swagger and sdk + // https://github.com/Azure/azure-rest-api-specs/issues/9076 + // directly use string constant + validation.StringInSlice([]string{ + "ActivityLog Administrative", + "ActivityLog Autoscale", + "ActivityLog Policy", + "ActivityLog Recommendation", + "ActivityLog Security", + "Application Insights", + "Azure Backup", + "Data Box Edge", + "Data Box Gateway", + "Health Platform", + "Log Analytics", + "Platform", + "Resource Health", + }, false), + ), - "severity": schemaActionRuleSeverityCondtion(), + "severity": schemaActionRuleCondition( + validation.StringInSlice([]string{ + string(alertsmanagement.Equals), + string(alertsmanagement.NotEquals), + }, false), + validation.StringInSlice([]string{ + string(alertsmanagement.Sev0), + string(alertsmanagement.Sev1), + string(alertsmanagement.Sev2), + string(alertsmanagement.Sev3), + string(alertsmanagement.Sev4), + }, false), + ), - "target_resource_type": schemaActionRuleTargetResourceTypeCondtion(), + "target_resource_type": schemaActionRuleCondition( + validation.StringInSlice([]string{ + string(alertsmanagement.Equals), + string(alertsmanagement.NotEquals), + }, false), + validation.StringIsNotEmpty, + ), }, }, }, @@ -209,7 +265,7 @@ func resourceArmMonitorActionRule() *schema.Resource { } } -func resourceArmMonitorActionRuleCreateUpdate(d *schema.ResourceData, meta interface{}) error { +func resourceArmMonitorActionRuleSuppressionCreateUpdate(d *schema.ResourceData, meta interface{}) error { client := meta.(*clients.Client).Monitor.ActionRulesClient ctx, cancel := timeouts.ForCreateUpdate(meta.(*clients.Client).StopContext, d) defer cancel() @@ -225,84 +281,52 @@ func resourceArmMonitorActionRuleCreateUpdate(d *schema.ResourceData, meta inter } } if existing.ID != nil && *existing.ID != "" { - return tf.ImportAsExistsError("azurerm_monitor_action_rule", *existing.ID) + return tf.ImportAsExistsError("azurerm_monitor_action_rule_suppression", *existing.ID) } } - actionRule := alertsmanagement.ActionRule{ - // the location is always global from the portal - Location: utils.String(location.Normalize("Global")), - Tags: tags.Expand(d.Get("tags").(map[string]interface{})), - } - - t := alertsmanagement.Type(d.Get("type").(string)) - description := d.Get("description").(string) - scope := expandArmActionRuleScope(d.Get("scope").([]interface{})) - conditions := expandArmActionRuleConditions(d.Get("condition").([]interface{})) - actionRuleStatus := alertsmanagement.Enabled if !d.Get("enabled").(bool) { actionRuleStatus = alertsmanagement.Disabled } - switch t { - case alertsmanagement.TypeSuppression: - suppressionConfig, err := expandArmActionRuleSuppressionConfig(d.Get("suppression").([]interface{})) - if err != nil { - return err - } - if suppressionConfig == nil { - return fmt.Errorf("`suppression` field must be set when type is `Suppression`.") - } - actionRule.Properties = &alertsmanagement.Suppression{ + suppressionConfig, err := expandArmActionRuleSuppressionConfig(d.Get("suppression").([]interface{})) + if err != nil { + return err + } + + actionRule := alertsmanagement.ActionRule{ + // the location is always global from the portal + Location: utils.String(location.Normalize("Global")), + Properties: &alertsmanagement.Suppression{ SuppressionConfig: suppressionConfig, - Scope: scope, - Conditions: conditions, - Description: utils.String(description), + Scope: expandArmActionRuleScope(d.Get("scope").([]interface{})), + Conditions: expandArmActionRuleConditions(d.Get("condition").([]interface{})), + Description: utils.String(d.Get("description").(string)), Status: actionRuleStatus, - Type: t, - } - case alertsmanagement.TypeActionGroup: - actionGroupId := d.Get("action_group_id").(string) - if actionGroupId == "" { - return fmt.Errorf("`action_group_id` field must be set when type is `ActionGroup`.") - } - actionRule.Properties = &alertsmanagement.ActionGroup{ - ActionGroupID: utils.String(actionGroupId), - Scope: scope, - Conditions: conditions, - Description: utils.String(description), - Status: actionRuleStatus, - Type: t, - } - case alertsmanagement.TypeDiagnostics: - actionRule.Properties = &alertsmanagement.Diagnostics{ - Scope: scope, - Conditions: conditions, - Description: utils.String(description), - Status: actionRuleStatus, - Type: t, - } + Type: alertsmanagement.TypeSuppression, + }, + Tags: tags.Expand(d.Get("tags").(map[string]interface{})), } if _, err := client.CreateUpdate(ctx, resourceGroup, name, actionRule); err != nil { - return fmt.Errorf("creating/updatinge AlertsManagement ActionRule %q (Resource Group %q): %+v", name, resourceGroup, err) + return fmt.Errorf("creating/updatinge Monitor ActionRule %q (Resource Group %q): %+v", name, resourceGroup, err) } resp, err := client.GetByName(ctx, resourceGroup, name) if err != nil { - return fmt.Errorf("retrieving AlertsManagement ActionRule %q (Resource Group %q): %+v", name, resourceGroup, err) + return fmt.Errorf("retrieving Monitor ActionRule %q (Resource Group %q): %+v", name, resourceGroup, err) } if resp.ID == nil || *resp.ID == "" { - return fmt.Errorf("empty or nil ID returned for AlertsManagement ActionRule %q (Resource Group %q): %+v", name, resourceGroup, err) + return fmt.Errorf("empty or nil ID returned for Monitor ActionRule %q (Resource Group %q): %+v", name, resourceGroup, err) } d.SetId(*resp.ID) - return resourceArmMonitorActionRuleRead(d, meta) + return resourceArmMonitorActionRuleSuppressionRead(d, meta) } -func resourceArmMonitorActionRuleRead(d *schema.ResourceData, meta interface{}) error { +func resourceArmMonitorActionRuleSuppressionRead(d *schema.ResourceData, meta interface{}) error { client := meta.(*clients.Client).Monitor.ActionRulesClient ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) defer cancel() @@ -324,50 +348,25 @@ func resourceArmMonitorActionRuleRead(d *schema.ResourceData, meta interface{}) d.Set("name", resp.Name) d.Set("resource_group_name", id.ResourceGroup) - if resp.Properties != nil { - switch props := resp.Properties.(type) { - case alertsmanagement.Suppression: - if err := d.Set("suppression", flattenArmActionRuleSuppression(props.SuppressionConfig)); err != nil { - return fmt.Errorf("setting suppression: %+v", err) - } - if err := d.Set("scope", flattenArmActionRuleScope(props.Scope)); err != nil { - return fmt.Errorf("setting scope: %+v", err) - } - if err := d.Set("condition", flattenArmActionRuleConditions(props.Conditions)); err != nil { - return fmt.Errorf("setting condition: %+v", err) - } - d.Set("type", string(props.Type)) - d.Set("description", props.Description) - d.Set("enabled", props.Status == alertsmanagement.Enabled) - case alertsmanagement.ActionGroup: - if err := d.Set("scope", flattenArmActionRuleScope(props.Scope)); err != nil { - return fmt.Errorf("setting scope: %+v", err) - } - if err := d.Set("condition", flattenArmActionRuleConditions(props.Conditions)); err != nil { - return fmt.Errorf("setting condition: %+v", err) - } - d.Set("type", string(props.Type)) - d.Set("description", props.Description) - d.Set("enabled", props.Status == alertsmanagement.Enabled) - d.Set("action_group_id", props.ActionGroupID) - case alertsmanagement.Diagnostics: - if err := d.Set("scope", flattenArmActionRuleScope(props.Scope)); err != nil { - return fmt.Errorf("setting scope: %+v", err) - } - if err := d.Set("condition", flattenArmActionRuleConditions(props.Conditions)); err != nil { - return fmt.Errorf("setting condition: %+v", err) - } - d.Set("type", string(props.Type)) - d.Set("description", props.Description) - d.Set("enabled", props.Status == alertsmanagement.Enabled) + props, _ := resp.Properties.AsSuppression() + d.Set("description", props.Description) + d.Set("enabled", props.Status == alertsmanagement.Enabled) + if err := d.Set("suppression", flattenArmActionRuleSuppression(props.SuppressionConfig)); err != nil { + return fmt.Errorf("setting suppression: %+v", err) + } + if err := d.Set("scope", flattenArmActionRuleScope(props.Scope)); err != nil { + return fmt.Errorf("setting scope: %+v", err) + } + if err := d.Set("condition", flattenArmActionRuleConditions(props.Conditions)); err != nil { + return fmt.Errorf("setting condition: %+v", err) } } return tags.FlattenAndSet(d, resp.Tags) } -func resourceArmMonitorActionRuleDelete(d *schema.ResourceData, meta interface{}) error { +func resourceArmMonitorActionRuleSuppressionDelete(d *schema.ResourceData, meta interface{}) error { client := meta.(*clients.Client).Monitor.ActionRulesClient ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d) defer cancel() @@ -383,35 +382,6 @@ func resourceArmMonitorActionRuleDelete(d *schema.ResourceData, meta interface{} return nil } -func expandArmActionRuleScope(input []interface{}) *alertsmanagement.Scope { - if len(input) == 0 { - return nil - } - - v := input[0].(map[string]interface{}) - return &alertsmanagement.Scope{ - ScopeType: alertsmanagement.ScopeType(v["type"].(string)), - Values: utils.ExpandStringSlice(v["resource_ids"].(*schema.Set).List()), - } -} - -func expandArmActionRuleConditions(input []interface{}) *alertsmanagement.Conditions { - if len(input) == 0 { - return nil - } - v := input[0].(map[string]interface{}) - - return &alertsmanagement.Conditions{ - AlertContext: expandArmActionRuleCondition(v["alert_context"].([]interface{})), - AlertRuleID: expandArmActionRuleCondition(v["alert_rule_id"].([]interface{})), - Description: expandArmActionRuleCondition(v["description"].([]interface{})), - MonitorCondition: expandArmActionRuleCondition(v["monitor"].([]interface{})), - MonitorService: expandArmActionRuleCondition(v["monitor_service"].([]interface{})), - Severity: expandArmActionRuleCondition(v["severity"].([]interface{})), - TargetResourceType: expandArmActionRuleCondition(v["target_resource_type"].([]interface{})), - } -} - func expandArmActionRuleSuppressionConfig(input []interface{}) (*alertsmanagement.SuppressionConfig, error) { if len(input) == 0 { return nil, nil @@ -477,40 +447,6 @@ func expandArmActionRuleSuppressionScheduleRecurrenceWeekly(input []interface{}) return result } -func flattenArmActionRuleScope(input *alertsmanagement.Scope) []interface{} { - if input == nil { - return make([]interface{}, 0) - } - - var scopeType alertsmanagement.ScopeType - if input.ScopeType != "" { - scopeType = input.ScopeType - } - return []interface{}{ - map[string]interface{}{ - "type": scopeType, - "resource_ids": utils.FlattenStringSlice(input.Values), - }, - } -} - -func flattenArmActionRuleConditions(input *alertsmanagement.Conditions) []interface{} { - if input == nil { - return make([]interface{}, 0) - } - return []interface{}{ - map[string]interface{}{ - "alert_context": flattenArmActionRuleCondition(input.AlertContext), - "alert_rule_id": flattenArmActionRuleCondition(input.AlertRuleID), - "description": flattenArmActionRuleCondition(input.Description), - "monitor": flattenArmActionRuleCondition(input.MonitorCondition), - "monitor_service": flattenArmActionRuleCondition(input.MonitorService), - "severity": flattenArmActionRuleCondition(input.Severity), - "target_resource_type": flattenArmActionRuleCondition(input.TargetResourceType), - }, - } -} - func flattenArmActionRuleSuppression(input *alertsmanagement.SuppressionConfig) []interface{} { if input == nil { return make([]interface{}, 0) @@ -579,13 +515,3 @@ func flattenArmActionRuleSuppressionScheduleRecurrenceWeekly(input *[]int32) []i } return result } - -func FlattenInt32Slice(input *[]int32) []interface{} { - result := make([]interface{}, 0) - if input != nil { - for _, item := range *input { - result = append(result, item) - } - } - return result -} diff --git a/azurerm/internal/services/monitor/registration.go b/azurerm/internal/services/monitor/registration.go index a5b7454a885b..01b0ff1bceed 100644 --- a/azurerm/internal/services/monitor/registration.go +++ b/azurerm/internal/services/monitor/registration.go @@ -33,7 +33,8 @@ func (r Registration) SupportedResources() map[string]*schema.Resource { return map[string]*schema.Resource{ "azurerm_monitor_autoscale_setting": resourceArmMonitorAutoScaleSetting(), "azurerm_monitor_action_group": resourceArmMonitorActionGroup(), - "azurerm_monitor_action_rule": resourceArmMonitorActionRule(), + "azurerm_monitor_action_rule_action_group": resourceArmMonitorActionRuleActionGroup(), + "azurerm_monitor_action_rule_suppression": resourceArmMonitorActionRuleSuppression(), "azurerm_monitor_activity_log_alert": resourceArmMonitorActivityLogAlert(), "azurerm_monitor_diagnostic_setting": resourceArmMonitorDiagnosticSetting(), "azurerm_monitor_log_profile": resourceArmMonitorLogProfile(), diff --git a/azurerm/internal/services/monitor/tests/monitor_action_rule_action_group_resource_test.go b/azurerm/internal/services/monitor/tests/monitor_action_rule_action_group_resource_test.go new file mode 100644 index 000000000000..f0174fd04c62 --- /dev/null +++ b/azurerm/internal/services/monitor/tests/monitor_action_rule_action_group_resource_test.go @@ -0,0 +1,252 @@ +package tests + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/acceptance" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/monitor/parse" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMMonitorActionRuleActionGroup_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_monitor_action_rule_action_group", "test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMMonitorActionRuleActionGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMMonitorActionRuleActionGroup_basic(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMonitorActionRuleActionGroupExists(data.ResourceName), + ), + }, + data.ImportStep(), + }, + }) +} + +func TestAccAzureRMMonitorActionRuleActionGroup_requiresImport(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_monitor_action_rule_action_group", "test") + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMMonitorActionRuleActionGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMMonitorActionRuleActionGroup_basic(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMonitorActionRuleActionGroupExists(data.ResourceName), + ), + }, + data.RequiresImportErrorStep(testAccAzureRMMonitorActionRuleActionGroup_requiresImport), + }, + }) +} + +func TestAccAzureRMMonitorActionRuleActionGroup_complete(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_monitor_action_rule_action_group", "test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMMonitorActionRuleActionGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMMonitorActionRuleActionGroup_complete(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMonitorActionRuleActionGroupExists(data.ResourceName), + ), + }, + data.ImportStep(), + }, + }) +} + +func TestAccAzureRMMonitorActionRuleActionGroup_update(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_monitor_action_rule_action_group", "test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMMonitorActionRuleActionGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMMonitorActionRuleActionGroup_basic(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMonitorActionRuleActionGroupExists(data.ResourceName), + ), + }, + data.ImportStep(), + { + Config: testAccAzureRMMonitorActionRuleActionGroup_complete(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMonitorActionRuleActionGroupExists(data.ResourceName), + ), + }, + data.ImportStep(), + { + Config: testAccAzureRMMonitorActionRuleActionGroup_basic(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMonitorActionRuleActionGroupExists(data.ResourceName), + ), + }, + data.ImportStep(), + }, + }) +} + +func testCheckAzureRMMonitorActionRuleActionGroupExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + client := acceptance.AzureProvider.Meta().(*clients.Client).Monitor.ActionRulesClient + ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("can not found Monitor ActionRule: %s", resourceName) + } + id, err := parse.ActionRuleID(rs.Primary.ID) + if err != nil { + return err + } + if resp, err := client.GetByName(ctx, id.ResourceGroup, id.Name); err != nil { + if !utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("bad: monitor action_rule %q does not exist", id.Name) + } + return fmt.Errorf("bad: Get on Monitor ActionRulesClient: %+v", err) + } + return nil + } +} + +func testCheckAzureRMMonitorActionRuleActionGroupDestroy(s *terraform.State) error { + client := acceptance.AzureProvider.Meta().(*clients.Client).Monitor.ActionRulesClient + ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_monitor_action_rule_action_group" { + continue + } + id, err := parse.ActionRuleID(rs.Primary.ID) + if err != nil { + return err + } + if resp, err := client.GetByName(ctx, id.ResourceGroup, id.Name); err != nil { + if !utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("bad: Get on Monitor ActionRulesClient: %+v", err) + } + } + return nil + } + return nil +} + +func testAccAzureRMMonitorActionRuleActionGroup_basic(data acceptance.TestData) string { + template := testAccAzureRMMonitorActionRuleActionGroup_template(data) + return fmt.Sprintf(` +%s + +resource "azurerm_monitor_action_rule_action_group" "test" { + name = "acctest-moniter-%d" + resource_group_name = azurerm_resource_group.test.name + action_group_id = azurerm_monitor_action_group.test.id +} +`, template, data.RandomInteger) +} + +func testAccAzureRMMonitorActionRuleActionGroup_requiresImport(data acceptance.TestData) string { + template := testAccAzureRMMonitorActionRuleActionGroup_basic(data) + return fmt.Sprintf(` +%s + +resource "azurerm_monitor_action_rule_action_group" "import" { + name = azurerm_monitor_action_rule_action_group.test.name + resource_group_name = azurerm_monitor_action_rule_action_group.test.resource_group_name + action_group_id = azurerm_monitor_action_rule_action_group.test.action_group_id +} +`, template) +} + +func testAccAzureRMMonitorActionRuleActionGroup_complete(data acceptance.TestData) string { + template := testAccAzureRMMonitorActionRuleActionGroup_template(data) + return fmt.Sprintf(` +%s + +resource "azurerm_monitor_action_rule_action_group" "test" { + name = "acctest-moniter-%d" + resource_group_name = azurerm_resource_group.test.name + action_group_id = azurerm_monitor_action_group.test.id + enabled = false + description = "actionRule-test" + + scope { + type = "ResourceGroup" + resource_ids = [azurerm_resource_group.test.id] + } + + condition { + alert_context { + operator = "Contains" + values = ["context1", "context2"] + } + + alert_rule_id { + operator = "Contains" + values = ["ruleId1", "ruleId2"] + } + + description { + operator = "DoesNotContain" + values = ["description1", "description2"] + } + + monitor { + operator = "NotEquals" + values = ["Fired"] + } + + monitor_service { + operator = "Equals" + values = ["Data Box Edge", "Data Box Gateway", "Resource Health"] + } + + severity { + operator = "Equals" + values = ["Sev0", "Sev1", "Sev2"] + } + + target_resource_type { + operator = "Equals" + values = ["Microsoft.Compute/VirtualMachines", "microsoft.batch/batchaccounts"] + } + } + + tags = { + ENV = "Test" + } +} +`, template, data.RandomInteger) +} + +func testAccAzureRMMonitorActionRuleActionGroup_template(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctest-rg-%d" + location = "%s" +} + +resource "azurerm_monitor_action_group" "test" { + name = "acctestActionGroup-%d" + resource_group_name = azurerm_resource_group.test.name + short_name = "acctestag" +} +`, data.RandomInteger, data.Locations.Primary, data.RandomInteger) +} diff --git a/azurerm/internal/services/monitor/tests/monitor_action_rule_suppression_resource_test.go b/azurerm/internal/services/monitor/tests/monitor_action_rule_suppression_resource_test.go new file mode 100644 index 000000000000..3a5d8c9325e5 --- /dev/null +++ b/azurerm/internal/services/monitor/tests/monitor_action_rule_suppression_resource_test.go @@ -0,0 +1,335 @@ +package tests + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/acceptance" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/monitor/parse" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMMonitorActionRuleSuppression_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_monitor_action_rule_suppression", "test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMMonitorActionRuleSuppressionDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMMonitorActionRuleSuppression_basic(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMonitorActionRuleSuppressionExists(data.ResourceName), + ), + }, + data.ImportStep(), + }, + }) +} + +func TestAccAzureRMMonitorActionRuleSuppression_requiresImport(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_monitor_action_rule_suppression", "test") + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMMonitorActionRuleSuppressionDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMMonitorActionRuleSuppression_basic(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMonitorActionRuleSuppressionExists(data.ResourceName), + ), + }, + data.RequiresImportErrorStep(testAccAzureRMMonitorActionRuleSuppression_requiresImport), + }, + }) +} + +func TestAccAzureRMMonitorActionRuleSuppression_complete(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_monitor_action_rule_suppression", "test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMMonitorActionRuleSuppressionDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMMonitorActionRuleSuppression_complete(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMonitorActionRuleSuppressionExists(data.ResourceName), + ), + }, + data.ImportStep(), + }, + }) +} + +func TestAccAzureRMMonitorActionRuleSuppression_updateSuppressionConfig(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_monitor_action_rule_suppression", "test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMMonitorActionRuleSuppressionDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMMonitorActionRuleSuppression_basic(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMonitorActionRuleSuppressionExists(data.ResourceName), + ), + }, + data.ImportStep(), + { + Config: testAccAzureRMMonitorActionRuleSuppression_dailyRecurrence(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMonitorActionRuleSuppressionExists(data.ResourceName), + ), + }, + data.ImportStep(), + { + Config: testAccAzureRMMonitorActionRuleSuppression_monthlyRecurrence(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMonitorActionRuleSuppressionExists(data.ResourceName), + ), + }, + data.ImportStep(), + { + Config: testAccAzureRMMonitorActionRuleSuppression_complete(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMonitorActionRuleSuppressionExists(data.ResourceName), + ), + }, + data.ImportStep(), + { + Config: testAccAzureRMMonitorActionRuleSuppression_basic(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMonitorActionRuleSuppressionExists(data.ResourceName), + ), + }, + data.ImportStep(), + }, + }) +} + +func testCheckAzureRMMonitorActionRuleSuppressionExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + client := acceptance.AzureProvider.Meta().(*clients.Client).Monitor.ActionRulesClient + ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("can not found Monitor ActionRule: %s", resourceName) + } + id, err := parse.ActionRuleID(rs.Primary.ID) + if err != nil { + return err + } + if resp, err := client.GetByName(ctx, id.ResourceGroup, id.Name); err != nil { + if !utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("bad: monitor action_rule %q does not exist", id.Name) + } + return fmt.Errorf("bad: Get on Monitor ActionRulesClient: %+v", err) + } + return nil + } +} + +func testCheckAzureRMMonitorActionRuleSuppressionDestroy(s *terraform.State) error { + client := acceptance.AzureProvider.Meta().(*clients.Client).Monitor.ActionRulesClient + ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_monitor_action_rule_suppression" { + continue + } + id, err := parse.ActionRuleID(rs.Primary.ID) + if err != nil { + return err + } + if resp, err := client.GetByName(ctx, id.ResourceGroup, id.Name); err != nil { + if !utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("bad: Get on Monitor ActionRulesClient: %+v", err) + } + } + return nil + } + return nil +} + +func testAccAzureRMMonitorActionRuleSuppression_basic(data acceptance.TestData) string { + template := testAccAzureRMMonitorActionRuleSuppression_template(data) + return fmt.Sprintf(` +%s + +resource "azurerm_monitor_action_rule_suppression" "test" { + name = "acctest-moniter-%d" + resource_group_name = azurerm_resource_group.test.name + + suppression { + recurrence_type = "Always" + } +} +`, template, data.RandomInteger) +} + +func testAccAzureRMMonitorActionRuleSuppression_requiresImport(data acceptance.TestData) string { + template := testAccAzureRMMonitorActionRuleSuppression_basic(data) + return fmt.Sprintf(` +%s + +resource "azurerm_monitor_action_rule_suppression" "import" { + name = azurerm_monitor_action_rule_suppression.test.name + resource_group_name = azurerm_monitor_action_rule_suppression.test.resource_group_name + + suppression { + recurrence_type = azurerm_monitor_action_rule_suppression.test.suppression.0.recurrence_type + } +} +`, template) +} + +func testAccAzureRMMonitorActionRuleSuppression_complete(data acceptance.TestData) string { + template := testAccAzureRMMonitorActionRuleSuppression_template(data) + return fmt.Sprintf(` +%s + +resource "azurerm_monitor_action_rule_suppression" "test" { + name = "acctest-moniter-%d" + resource_group_name = azurerm_resource_group.test.name + enabled = false + description = "actionRule-test" + + scope { + type = "ResourceGroup" + resource_ids = [azurerm_resource_group.test.id] + } + + suppression { + recurrence_type = "Weekly" + + schedule { + start_date = "12/09/2018" + start_time = "06:00:00" + end_date = "12/18/2018" + end_time = "14:00:00" + + recurrence_weekly = ["Sunday", "Monday", "Friday", "Saturday"] + } + } + + condition { + alert_context { + operator = "Contains" + values = ["context1", "context2"] + } + + alert_rule_id { + operator = "Contains" + values = ["ruleId1", "ruleId2"] + } + + description { + operator = "DoesNotContain" + values = ["description1", "description2"] + } + + monitor { + operator = "NotEquals" + values = ["Fired"] + } + + monitor_service { + operator = "Equals" + values = ["Data Box Edge", "Data Box Gateway", "Resource Health"] + } + + severity { + operator = "Equals" + values = ["Sev0", "Sev1", "Sev2"] + } + + target_resource_type { + operator = "Equals" + values = ["Microsoft.Compute/VirtualMachines", "microsoft.batch/batchaccounts"] + } + } + + tags = { + ENV = "Test" + } +} +`, template, data.RandomInteger) +} + +func testAccAzureRMMonitorActionRuleSuppression_dailyRecurrence(data acceptance.TestData) string { + template := testAccAzureRMMonitorActionRuleSuppression_template(data) + return fmt.Sprintf(` +%s + +resource "azurerm_monitor_action_rule_suppression" "test" { + name = "acctest-moniter-%d" + resource_group_name = azurerm_resource_group.test.name + + scope { + type = "ResourceGroup" + resource_ids = [azurerm_resource_group.test.id] + } + + suppression { + recurrence_type = "Daily" + + schedule { + start_date = "12/09/2018" + start_time = "06:00:00" + end_date = "12/18/2018" + end_time = "14:00:00" + } + } +} +`, template, data.RandomInteger) +} + +func testAccAzureRMMonitorActionRuleSuppression_monthlyRecurrence(data acceptance.TestData) string { + template := testAccAzureRMMonitorActionRuleSuppression_template(data) + return fmt.Sprintf(` +%s + +resource "azurerm_monitor_action_rule_suppression" "test" { + name = "acctest-moniter-%d" + resource_group_name = azurerm_resource_group.test.name + + scope { + type = "ResourceGroup" + resource_ids = [azurerm_resource_group.test.id] + } + + suppression { + recurrence_type = "Monthly" + + schedule { + start_date = "12/09/2018" + start_time = "06:00:00" + end_date = "12/18/2018" + end_time = "14:00:00" + recurrence_monthly = [1, 2, 15, 30, 31] + } + } +} +`, template, data.RandomInteger) +} + +func testAccAzureRMMonitorActionRuleSuppression_template(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctest-rg-%d" + location = "%s" +} +`, data.RandomInteger, data.Locations.Primary) +} diff --git a/azurerm/internal/services/monitor/tests/resource_arm_monitor_action_rule_test.go b/azurerm/internal/services/monitor/tests/resource_arm_monitor_action_rule_test.go deleted file mode 100644 index d65f14e7b53e..000000000000 --- a/azurerm/internal/services/monitor/tests/resource_arm_monitor_action_rule_test.go +++ /dev/null @@ -1,650 +0,0 @@ -package tests - -import ( - "fmt" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/terraform" - "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/acceptance" - "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients" - "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/monitor/parse" - "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" -) - -func TestAccAzureRMMonitorActionRule_diagnostics_basic(t *testing.T) { - data := acceptance.BuildTestData(t, "azurerm_monitor_action_rule", "test") - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acceptance.PreCheck(t) }, - Providers: acceptance.SupportedProviders, - CheckDestroy: testCheckAzureRMMonitorActionRuleDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMAlertsManagementActionRule_diagnostics_basic(data), - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMMonitorActionRuleExists(data.ResourceName), - ), - }, - data.ImportStep(), - }, - }) -} - -func TestAccAzureRMMonitorActionRule_diagnostics_requiresImport(t *testing.T) { - data := acceptance.BuildTestData(t, "azurerm_monitor_action_rule", "test") - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acceptance.PreCheck(t) }, - Providers: acceptance.SupportedProviders, - CheckDestroy: testCheckAzureRMMonitorActionRuleDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMAlertsManagementActionRule_diagnostics_basic(data), - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMMonitorActionRuleExists(data.ResourceName), - ), - }, - data.RequiresImportErrorStep(testAccAzureRMAlertsManagementActionRule_diagnostics_requiresImport), - }, - }) -} - -func TestAccAzureRMMonitorActionRule_diagnostics_complete(t *testing.T) { - data := acceptance.BuildTestData(t, "azurerm_monitor_action_rule", "test") - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acceptance.PreCheck(t) }, - Providers: acceptance.SupportedProviders, - CheckDestroy: testCheckAzureRMMonitorActionRuleDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMAlertsManagementActionRule_diagnostics_complete(data), - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMMonitorActionRuleExists(data.ResourceName), - ), - }, - data.ImportStep(), - }, - }) -} - -func TestAccAzureRMMonitorActionRule_diagnostics_update(t *testing.T) { - data := acceptance.BuildTestData(t, "azurerm_monitor_action_rule", "test") - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acceptance.PreCheck(t) }, - Providers: acceptance.SupportedProviders, - CheckDestroy: testCheckAzureRMMonitorActionRuleDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMAlertsManagementActionRule_diagnostics_basic(data), - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMMonitorActionRuleExists(data.ResourceName), - ), - }, - data.ImportStep(), - { - Config: testAccAzureRMAlertsManagementActionRule_diagnostics_complete(data), - Check: resource.ComposeTestCheckFunc(), - }, - data.ImportStep(), - { - Config: testAccAzureRMAlertsManagementActionRule_diagnostics_basic(data), - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMMonitorActionRuleExists(data.ResourceName), - ), - }, - data.ImportStep(), - }, - }) -} - -func TestAccAzureRMMonitorActionRule_actionGroup_basic(t *testing.T) { - data := acceptance.BuildTestData(t, "azurerm_monitor_action_rule", "test") - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acceptance.PreCheck(t) }, - Providers: acceptance.SupportedProviders, - CheckDestroy: testCheckAzureRMMonitorActionRuleDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMAlertsManagementActionRule_actionGroup_basic(data), - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMMonitorActionRuleExists(data.ResourceName), - ), - }, - data.ImportStep(), - }, - }) -} - -func TestAccAzureRMMonitorActionRule_actionGroup_complete(t *testing.T) { - data := acceptance.BuildTestData(t, "azurerm_monitor_action_rule", "test") - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acceptance.PreCheck(t) }, - Providers: acceptance.SupportedProviders, - CheckDestroy: testCheckAzureRMMonitorActionRuleDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMAlertsManagementActionRule_actionGroup_complete(data), - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMMonitorActionRuleExists(data.ResourceName), - ), - }, - data.ImportStep(), - }, - }) -} - -func TestAccAzureRMMonitorActionRule_actionGroup_update(t *testing.T) { - data := acceptance.BuildTestData(t, "azurerm_monitor_action_rule", "test") - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acceptance.PreCheck(t) }, - Providers: acceptance.SupportedProviders, - CheckDestroy: testCheckAzureRMMonitorActionRuleDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMAlertsManagementActionRule_actionGroup_basic(data), - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMMonitorActionRuleExists(data.ResourceName), - ), - }, - data.ImportStep(), - { - Config: testAccAzureRMAlertsManagementActionRule_actionGroup_complete(data), - Check: resource.ComposeTestCheckFunc(), - }, - data.ImportStep(), - { - Config: testAccAzureRMAlertsManagementActionRule_actionGroup_basic(data), - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMMonitorActionRuleExists(data.ResourceName), - ), - }, - data.ImportStep(), - }, - }) -} - -func TestAccAzureRMMonitorActionRule_suppression_basic(t *testing.T) { - data := acceptance.BuildTestData(t, "azurerm_monitor_action_rule", "test") - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acceptance.PreCheck(t) }, - Providers: acceptance.SupportedProviders, - CheckDestroy: testCheckAzureRMMonitorActionRuleDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMAlertsManagementActionRule_suppression_basic(data), - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMMonitorActionRuleExists(data.ResourceName), - ), - }, - data.ImportStep(), - }, - }) -} - -func TestAccAzureRMMonitorActionRule_suppression_complete(t *testing.T) { - data := acceptance.BuildTestData(t, "azurerm_monitor_action_rule", "test") - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acceptance.PreCheck(t) }, - Providers: acceptance.SupportedProviders, - CheckDestroy: testCheckAzureRMMonitorActionRuleDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMAlertsManagementActionRule_suppression_complete(data), - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMMonitorActionRuleExists(data.ResourceName), - ), - }, - data.ImportStep(), - }, - }) -} - -func TestAccAzureRMMonitorActionRule_suppression_updateSuppressionConfig(t *testing.T) { - data := acceptance.BuildTestData(t, "azurerm_monitor_action_rule", "test") - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acceptance.PreCheck(t) }, - Providers: acceptance.SupportedProviders, - CheckDestroy: testCheckAzureRMMonitorActionRuleDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMAlertsManagementActionRule_suppression_basic(data), - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMMonitorActionRuleExists(data.ResourceName), - ), - }, - data.ImportStep(), - { - Config: testAccAzureRMAlertsManagementActionRule_suppression_dailyRecurrence(data), - Check: resource.ComposeTestCheckFunc(), - }, - data.ImportStep(), - { - Config: testAccAzureRMAlertsManagementActionRule_suppression_monthlyRecurrence(data), - Check: resource.ComposeTestCheckFunc(), - }, - data.ImportStep(), - { - Config: testAccAzureRMAlertsManagementActionRule_suppression_complete(data), - Check: resource.ComposeTestCheckFunc(), - }, - data.ImportStep(), - { - Config: testAccAzureRMAlertsManagementActionRule_suppression_basic(data), - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMMonitorActionRuleExists(data.ResourceName), - ), - }, - data.ImportStep(), - }, - }) -} - -func testCheckAzureRMMonitorActionRuleExists(resourceName string) resource.TestCheckFunc { - return func(s *terraform.State) error { - client := acceptance.AzureProvider.Meta().(*clients.Client).Monitor.ActionRulesClient - ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext - rs, ok := s.RootModule().Resources[resourceName] - if !ok { - return fmt.Errorf("can not found AlertsManagement ActionRule: %s", resourceName) - } - id, err := parse.ActionRuleID(rs.Primary.ID) - if err != nil { - return err - } - if resp, err := client.GetByName(ctx, id.ResourceGroup, id.Name); err != nil { - if !utils.ResponseWasNotFound(resp.Response) { - return fmt.Errorf("bad: alerts_management action_rule %q does not exist", id.Name) - } - return fmt.Errorf("bad: Get on AlertsManagement ActionRulesClient: %+v", err) - } - return nil - } -} - -func testCheckAzureRMMonitorActionRuleDestroy(s *terraform.State) error { - client := acceptance.AzureProvider.Meta().(*clients.Client).Monitor.ActionRulesClient - ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext - - for _, rs := range s.RootModule().Resources { - if rs.Type != "azurerm_monitor_action_rule" { - continue - } - id, err := parse.ActionRuleID(rs.Primary.ID) - if err != nil { - return err - } - if resp, err := client.GetByName(ctx, id.ResourceGroup, id.Name); err != nil { - if !utils.ResponseWasNotFound(resp.Response) { - return fmt.Errorf("bad: Get on AlertsManagement ActionRulesClient: %+v", err) - } - } - return nil - } - return nil -} - -func testAccAzureRMAlertsManagementActionRule_diagnostics_basic(data acceptance.TestData) string { - template := testAccAzureRMAlertsManagementActionRule_template(data) - return fmt.Sprintf(` -%s - -resource "azurerm_monitor_action_rule" "test" { - name = "acctest-ar-%d" - resource_group_name = azurerm_resource_group.test.name - type = "Diagnostics" -} -`, template, data.RandomInteger) -} - -func testAccAzureRMAlertsManagementActionRule_diagnostics_requiresImport(data acceptance.TestData) string { - template := testAccAzureRMAlertsManagementActionRule_diagnostics_basic(data) - return fmt.Sprintf(` -%s - -resource "azurerm_monitor_action_rule" "import" { - name = azurerm_monitor_action_rule.test.name - resource_group_name = azurerm_monitor_action_rule.test.resource_group_name - type = "Diagnostics" - - scope { - type = "ResourceGroup" - resource_ids = [azurerm_resource_group.test.id] - } -} -`, template) -} - -func testAccAzureRMAlertsManagementActionRule_diagnostics_complete(data acceptance.TestData) string { - template := testAccAzureRMAlertsManagementActionRule_template(data) - return fmt.Sprintf(` -%s - -resource "azurerm_monitor_action_rule" "test" { - name = "acctest-ar-%d" - resource_group_name = azurerm_resource_group.test.name - type = "Diagnostics" - enabled = false - description = "actionRule-test" - - scope { - type = "ResourceGroup" - resource_ids = [azurerm_resource_group.test.id] - } - - condition { - alert_context { - operator = "Contains" - values = ["context1", "context2"] - } - - alert_rule_id { - operator = "Contains" - values = ["ruleId1", "ruleId2"] - } - - description { - operator = "DoesNotContain" - values = ["description1", "description2"] - } - - monitor { - operator = "NotEquals" - values = ["Fired"] - } - - monitor_service { - operator = "Equals" - values = ["Data Box Edge", "Data Box Gateway", "Resource Health"] - } - - severity { - operator = "Equals" - values = ["Sev0", "Sev1", "Sev2"] - } - - target_resource_type { - operator = "Equals" - values = ["Microsoft.Compute/VirtualMachines", "microsoft.batch/batchaccounts"] - } - } - - tags = { - ENV = "Test" - } -} -`, template, data.RandomInteger) -} - -func testAccAzureRMAlertsManagementActionRule_actionGroup_basic(data acceptance.TestData) string { - template := testAccAzureRMAlertsManagementActionRule_actionGroup_template(data) - return fmt.Sprintf(` -%s - -resource "azurerm_monitor_action_rule" "test" { - name = "acctest-ar-%d" - resource_group_name = azurerm_resource_group.test.name - type = "ActionGroup" - action_group_id = azurerm_monitor_action_group.test.id -} -`, template, data.RandomInteger) -} - -func testAccAzureRMAlertsManagementActionRule_actionGroup_complete(data acceptance.TestData) string { - template := testAccAzureRMAlertsManagementActionRule_actionGroup_template(data) - return fmt.Sprintf(` -%s - -resource "azurerm_monitor_action_rule" "test" { - name = "acctest-ar-%d" - resource_group_name = azurerm_resource_group.test.name - type = "ActionGroup" - action_group_id = azurerm_monitor_action_group.test.id - enabled = false - description = "actionRule-test" - - scope { - type = "ResourceGroup" - resource_ids = [azurerm_resource_group.test.id] - } - - condition { - alert_context { - operator = "Contains" - values = ["context1", "context2"] - } - - alert_rule_id { - operator = "Contains" - values = ["ruleId1", "ruleId2"] - } - - description { - operator = "DoesNotContain" - values = ["description1", "description2"] - } - - monitor { - operator = "NotEquals" - values = ["Fired"] - } - - monitor_service { - operator = "Equals" - values = ["Data Box Edge", "Data Box Gateway", "Resource Health"] - } - - severity { - operator = "Equals" - values = ["Sev0", "Sev1", "Sev2"] - } - - target_resource_type { - operator = "Equals" - values = ["Microsoft.Compute/VirtualMachines", "microsoft.batch/batchaccounts"] - } - } - - tags = { - ENV = "Test" - } -} -`, template, data.RandomInteger) -} - -func testAccAzureRMAlertsManagementActionRule_suppression_basic(data acceptance.TestData) string { - template := testAccAzureRMAlertsManagementActionRule_template(data) - return fmt.Sprintf(` -%s - -resource "azurerm_monitor_action_rule" "test" { - name = "acctest-ar-%d" - resource_group_name = azurerm_resource_group.test.name - type = "Suppression" - - suppression { - recurrence_type = "Always" - } -} -`, template, data.RandomInteger) -} - -func testAccAzureRMAlertsManagementActionRule_suppression_complete(data acceptance.TestData) string { - template := testAccAzureRMAlertsManagementActionRule_template(data) - return fmt.Sprintf(` -%s - -resource "azurerm_storage_account" "test" { - name = "acctest%s" - resource_group_name = azurerm_resource_group.test.name - location = azurerm_resource_group.test.location - account_tier = "Standard" - account_replication_type = "LRS" -} - -resource "azurerm_monitor_action_rule" "test" { - name = "acctest-ar-%d" - resource_group_name = azurerm_resource_group.test.name - type = "Suppression" - enabled = false - description = "actionRule-test" - - scope { - type = "ResourceGroup" - resource_ids = [azurerm_resource_group.test.id] - } - - suppression { - recurrence_type = "Weekly" - - schedule { - start_date = "12/09/2018" - start_time = "06:00:00" - end_date = "12/18/2018" - end_time = "14:00:00" - - recurrence_weekly = ["Sunday", "Monday", "Friday", "Saturday"] - } - } - - condition { - alert_context { - operator = "Contains" - values = ["context1", "context2"] - } - - alert_rule_id { - operator = "Contains" - values = ["ruleId1", "ruleId2"] - } - - description { - operator = "DoesNotContain" - values = ["description1", "description2"] - } - - monitor { - operator = "NotEquals" - values = ["Fired"] - } - - monitor_service { - operator = "Equals" - values = ["Data Box Edge", "Data Box Gateway", "Resource Health"] - } - - severity { - operator = "Equals" - values = ["Sev0", "Sev1", "Sev2"] - } - - target_resource_type { - operator = "Equals" - values = ["Microsoft.Compute/VirtualMachines", "microsoft.batch/batchaccounts"] - } - } - - tags = { - ENV = "Test" - } -} -`, template, data.RandomString, data.RandomInteger) -} - -func testAccAzureRMAlertsManagementActionRule_suppression_dailyRecurrence(data acceptance.TestData) string { - template := testAccAzureRMAlertsManagementActionRule_template(data) - return fmt.Sprintf(` -%s - -resource "azurerm_monitor_action_rule" "test" { - name = "acctest-ar-%d" - resource_group_name = azurerm_resource_group.test.name - type = "Suppression" - - scope { - type = "ResourceGroup" - resource_ids = [azurerm_resource_group.test.id] - } - - suppression { - recurrence_type = "Daily" - - schedule { - start_date = "12/09/2018" - start_time = "06:00:00" - end_date = "12/18/2018" - end_time = "14:00:00" - } - } -} -`, template, data.RandomInteger) -} - -func testAccAzureRMAlertsManagementActionRule_suppression_monthlyRecurrence(data acceptance.TestData) string { - template := testAccAzureRMAlertsManagementActionRule_template(data) - return fmt.Sprintf(` -%s - -resource "azurerm_monitor_action_rule" "test" { - name = "acctest-ar-%d" - resource_group_name = azurerm_resource_group.test.name - type = "Suppression" - - scope { - type = "ResourceGroup" - resource_ids = [azurerm_resource_group.test.id] - } - - suppression { - recurrence_type = "Monthly" - - schedule { - start_date = "12/09/2018" - start_time = "06:00:00" - end_date = "12/18/2018" - end_time = "14:00:00" - recurrence_monthly = [1, 2, 15, 30, 31] - } - } -} -`, template, data.RandomInteger) -} - -func testAccAzureRMAlertsManagementActionRule_template(data acceptance.TestData) string { - return fmt.Sprintf(` -provider "azurerm" { - features {} -} - -resource "azurerm_resource_group" "test" { - name = "acctest-rg-%d" - location = "%s" -} -`, data.RandomInteger, data.Locations.Primary) -} - -func testAccAzureRMAlertsManagementActionRule_actionGroup_template(data acceptance.TestData) string { - return fmt.Sprintf(` -provider "azurerm" { - features {} -} - -resource "azurerm_resource_group" "test" { - name = "acctest-rg-%d" - location = "%s" -} - -resource "azurerm_monitor_action_group" "test" { - name = "acctestActionGroup-%d" - resource_group_name = azurerm_resource_group.test.name - short_name = "acctestag" -} -`, data.RandomInteger, data.Locations.Primary, data.RandomInteger) -} diff --git a/website/azurerm.erb b/website/azurerm.erb index 16ef45df00ca..a303a46e9758 100644 --- a/website/azurerm.erb +++ b/website/azurerm.erb @@ -1921,7 +1921,11 @@
  • - azurerm_monitor_action_rule + azurerm_monitor_action_rule_action_group +
  • + +
  • + azurerm_monitor_action_rule_suppression
  • diff --git a/website/docs/r/monitor_action_rule_action_group.html.markdown b/website/docs/r/monitor_action_rule_action_group.html.markdown new file mode 100644 index 000000000000..4e1fcae46673 --- /dev/null +++ b/website/docs/r/monitor_action_rule_action_group.html.markdown @@ -0,0 +1,168 @@ +--- +subcategory: "Monitor" +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_monitor_action_rule_action_group" +description: |- + Manages an Monitor Action Rule which type is action group. +--- + +# azurerm_monitor_action_rule_action_group + +Manages an Monitor Action Rule which type is action group. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "example-resources" + location = "West Europe" +} + +resource "azurerm_monitor_action_group" "example" { + name = "example-action-group" + resource_group_name = azurerm_resource_group.example.name + short_name = "exampleactiongroup" +} + +resource "azurerm_monitor_action_rule_action_group" "example" { + name = "example-amar" + resource_group_name = azurerm_resource_group.example.name + action_group_id = azurerm_monitor_action_group.example.id + + scope { + type = "ResourceGroup" + resource_ids = [azurerm_resource_group.example.id] + } + + tags = { + foo = "bar" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the Monitor Action Rule. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) Specifies the name of the resource group in which the Monitor Action Rule should exist. Changing this forces a new resource to be created. + +* `action_group_id` - (Required) Specifies the resource id of monitor action group. + +* `description` - (Optional) Specifies a description for the Action Rule. + +* `enabled` - (Optional) Is the Action Rule enabled? Defaults to `true`. + +* `scope` - (Optional) A `scope` block as defined below. + +* `condition` - (Optional) A `condition` block as defined below. + +* `tags` - (Optional) A mapping of tags to assign to the resource. + +--- + +The `scope` block supports the following: + +* `type` - (Required) Specifies the type of target scope. Possible values are `ResourceGroup` and `Resource`. + +* `resource_ids` - (Required) A list of resource IDs of the given scope type which will be the target of action rule. + +--- + +The `condition` block supports the following: + +* `alert_context` - (Optional) A `alert_context` block as defined below. + +* `alert_rule_id` - (Optional) A `alert_rule_id` block as defined below. + +* `description` - (Optional) A `description` block as defined below. + +* `monitor` - (Optional) A `monitor` block as defined below. + +* `monitor_service` - (Optional) A `monitor_service` as block defined below. + +* `severity` - (Optional) A `severity` block as defined below. + +* `target_resource_type` - (Optional) A `target_resource_type` block as defined below. + +--- + +The `alert_context` block supports the following: + +* `operator` - (Required) The operator for a given condition. Possible values are `Equals`, `NotEquals`, `Contains`, and `DoesNotContain`. + +* `values` - (Required) A list of values to match for a given condition. + +--- + +The `alert_rule_id` block supports the following: + +* `operator` - (Required) The operator for a given condition. Possible values are `Equals`, `NotEquals`, `Contains`, and `DoesNotContain`. + +* `values` - (Required) A list of values to match for a given condition. + +--- + +The `description` block supports the following: + +* `operator` - (Required) The operator for a given condition. Possible values are `Equals`, `NotEquals`, `Contains`, and `DoesNotContain`. + +* `values` - (Required) A list of values to match for a given condition. + +--- + +The `monitor` block supports the following: + +* `operator` - (Required) The operator for a given condition. Possible values are `Equals` and `NotEquals`. + +* `values` - (Required) A list of values to match for a given condition. Possible values are `Fired` and `Resolved`. + +--- + +The `monitor_service` block supports the following: + +* `operator` - (Required) The operator for a given condition. Possible values are `Equals` and `NotEquals`. + +* `values` - (Required) A list of values to match for a given condition. Possible values are `ActivityLog Administrative`, `ActivityLog Autoscale`, `ActivityLog Policy`, `ActivityLog Recommendation`, `ActivityLog Security`, `Application Insights`, `Azure Backup`, `Data Box Edge`, `Data Box Gateway`, `Health Platform`, `Log Analytics`, `Platform`, and `Resource Health`. + +--- + +The `severity` block supports the following: + +* `operator` - (Required) The operator for a given condition. Possible values are `Equals`and `NotEquals`. + +* `values` - (Required) A list of values to match for a given condition. Possible values are `Sev0`, `Sev1`, `Sev2`, `Sev3`, and `Sev4`. + +--- + +The `target_resource_type` block supports the following: + +* `operator` - (Required) The operator for a given condition. Possible values are `Equals` and `NotEquals`. + +* `values` - (Required) A list of values to match for a given condition. The values should be valid resource types. + +--- + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the Monitor Action Rule. + +## Timeouts + +The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/docs/configuration/resources.html#timeouts) for certain actions: + +* `create` - (Defaults to 30 minutes) Used when creating the Monitor Action Rule. +* `read` - (Defaults to 5 minutes) Used when retrieving the Monitor Action Rule. +* `update` - (Defaults to 30 minutes) Used when updating the Monitor Action Rule. +* `delete` - (Defaults to 30 minutes) Used when deleting the Monitor Action Rule. + +## Import + +Monitor Action Rule can be imported using the `resource id`, e.g. + +```shell +$ terraform import azurerm_monitor_action_rule_action_group.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.AlertsManagement/actionRules/actionRule1 +``` diff --git a/website/docs/r/monitor_action_rule.html.markdown b/website/docs/r/monitor_action_rule_suppression.html.markdown similarity index 51% rename from website/docs/r/monitor_action_rule.html.markdown rename to website/docs/r/monitor_action_rule_suppression.html.markdown index b1ffb8d1faf6..7a6f6aa308c2 100644 --- a/website/docs/r/monitor_action_rule.html.markdown +++ b/website/docs/r/monitor_action_rule_suppression.html.markdown @@ -1,59 +1,26 @@ --- subcategory: "Monitor" layout: "azurerm" -page_title: "Azure Resource Manager: azurerm_monitor_action_rule" +page_title: "Azure Resource Manager: azurerm_monitor_action_rule_suppression" description: |- - Manages an Monitor Action Rule. + Manages an Monitor Action Rule which type is suppression. --- -# azurerm_monitor_action_rule +# azurerm_monitor_action_rule_suppression -Manages an Monitor Action Rule. +Manages an Monitor Action Rule which type is suppression. -## Diagnostics Action Rule Example Usage +## Example Usage ```hcl -provider "azurerm" { - features {} -} - -resource "azurerm_resource_group" "example" { - name = "example-resources" - location = "West Europe" -} - -resource "azurerm_monitor_action_rule" "example" { - name = "example-amar" - resource_group_name = azurerm_resource_group.example.name - type = "Diagnostics" - - scope { - type = "ResourceGroup" - resource_ids = [azurerm_resource_group.example.id] - } - - tags = { - foo = "bar" - } -} -``` - -## Suppression Action Rule Example Usage - -```hcl -provider "azurerm" { - features {} -} - resource "azurerm_resource_group" "example" { name = "example-resources" location = "West Europe" } -resource "azurerm_monitor_action_rule" "example" { +resource "azurerm_monitor_action_rule_suppression" "example" { name = "example-amar" resource_group_name = azurerm_resource_group.example.name - type = "Suppression" scope { type = "ResourceGroup" @@ -79,41 +46,6 @@ resource "azurerm_monitor_action_rule" "example" { } ``` -## ActionGroup Action Rule Example Usage - -```hcl -provider "azurerm" { - features {} -} - -resource "azurerm_resource_group" "example" { - name = "example-resources" - location = "West Europe" -} - -resource "azurerm_monitor_action_group" "example" { - name = "example-action-group" - resource_group_name = azurerm_resource_group.example.name - short_name = "exampleactiongroup" -} - -resource "azurerm_monitor_action_rule" "example" { - name = "example-amar" - resource_group_name = azurerm_resource_group.example.name - type = "ActionGroup" - action_group_id = azurerm_monitor_action_group.example.id - - scope { - type = "ResourceGroup" - resource_ids = [azurerm_resource_group.example.id] - } - - tags = { - foo = "bar" - } -} -``` - ## Argument Reference The following arguments are supported: @@ -122,19 +54,15 @@ The following arguments are supported: * `resource_group_name` - (Required) Specifies the name of the resource group in which the Monitor Action Rule should exist. Changing this forces a new resource to be created. -* `type` - (Required) Specifies the type of the Action Rule. Possible values are `Suppression`, `ActionGroup` and `Diagnostics`. Changing this forces a new resource to be created. +* `suppression` - (Required) A `suppression` block as defined below. * `description` - (Optional) Specifies a description for the Action Rule. * `enabled` - (Optional) Is the Action Rule enabled? Defaults to `true`. -* `action_group_id` - (Optional) Specifies the resource id of monitor action group. Required only if `type` is `ActionGroup`. - -* `suppression` - (Optional) One `suppression` as defined below. Required only if `type` is `Suppression`. - -* `scope` - (Optional) One `scope` block as defined below. +* `scope` - (Optional) A `scope` block as defined below. -* `condition` - (Optional) One `condition` block as defined below. +* `condition` - (Optional) A `condition` block as defined below. * `tags` - (Optional) A mapping of tags to assign to the resource. @@ -142,56 +70,57 @@ The following arguments are supported: The `suppression` block supports the following: -* `recurrence_type` - (Required) Specifies the type of suppression. Possible values are `Always`, `Daily`, `Monthly`, `Once` and `Weekly`. +* `recurrence_type` - (Required) Specifies the type of suppression. Possible values are `Always`, `Daily`, `Monthly`, `Once`, and `Weekly`. -* `schedule` - (Optional) One `schedule` block as defined below. Required if `recurrence_type` is `Daily`, `Monthly`, `Once` or `Weekly`. ---- +* `schedule` - (Optional) A `schedule` block as defined below. Required if `recurrence_type` is `Daily`, `Monthly`, `Once` or `Weekly`. -The `scope` block supports the following: +--- -* `type` - (Required) Specifies the type of target scope. Possible values are `ResourceGroup` and `Resource`. +The `schedule` block supports the following: -* `resource_ids` - (Required) A list of resource IDs of the given scope type which will be the target of action rule. +* `start_date` - (Required) specifies the UTC start date of recurrence range. The format should be `MM/DD/YYYY`. ---- +* `start_time` - (Required) specifies the UTC start time of recurrence range. The format should be `HH:MM:SS`. -The `condition` block supports the following: +* `end_date` - (Required) specifies the UTC end date of recurrence range. The format should be `MM/DD/YYYY`. -* `alert_context` - (Optional) One `alert_context` block as defined below. +* `end_time` - (Required) specifies the UTC end time of recurrence range. The format should be `HH:MM:SS`. -* `alert_rule_id` - (Optional) One `alert_rule_id` block as defined below. +* `recurrence_weekly` - (Optional) specifies the list of dayOfWeek to recurrence. Possible values are `Sunday`, `Monday`, `Tuesday`, `Wednesday`, `Thursday`, `Friday` and `Saturday`. -* `description` - (Optional) One `description` block as defined below. +* `recurrence_monthly` - (Optional) specifies the list of dayOfMonth to recurrence. Possible values are between `1` - `31`. Required if `recurrence_type` is `Monthly`. -* `monitor` - (Optional) One `monitor` block as defined below. +--- -* `monitor_service` - (Optional) One `monitor_service` as block defined below. +The `scope` block supports the following: -* `severity` - (Optional) One `severity` block as defined below. +* `type` - (Required) Specifies the type of target scope. Possible values are `ResourceGroup` and `Resource`. -* `target_resource_type` - (Optional) One `target_resource_type` block as defined below. +* `resource_ids` - (Required) A list of resource IDs of the given scope type which will be the target of action rule. --- -The `schedule` block supports the following: +The `condition` block supports the following: -* `start_date` - (Required) specifies the UTC start date of recurrence range. The format should be `MM/DD/YYYY`. +* `alert_context` - (Optional) A `alert_context` block as defined below. -* `start_time` - (Required) specifies the UTC start time of recurrence range. The format should be `HH:MM:SS`. +* `alert_rule_id` - (Optional) A `alert_rule_id` block as defined below. -* `end_date` - (Required) specifies the UTC end date of recurrence range. The format should be `MM/DD/YYYY`. +* `description` - (Optional) A `description` block as defined below. -* `end_time` - (Required) specifies the UTC end time of recurrence range. The format should be `HH:MM:SS`. +* `monitor` - (Optional) A `monitor` block as defined below. -* `recurrence_weekly` - (Optional) specifies the list of dayOfWeek to recurrence. Possible values are `Sunday`, `Monday`, `Tuesday`, `Wednesday`, `Thursday`, `Friday` and `Saturday`. +* `monitor_service` - (Optional) A `monitor_service` as block defined below. -* `recurrence_monthly` - (Optional) specifies the list of dayOfMonth to recurrence. Possible values are between `1` - `31`. Required if `recurrence_type` is `Monthly`. +* `severity` - (Optional) A `severity` block as defined below. + +* `target_resource_type` - (Optional) A `target_resource_type` block as defined below. --- The `alert_context` block supports the following: -* `operator` - (Required) operator for a given condition. Possible values are `Equals`, `NotEquals`, `Contains` and `DoesNotContain`. +* `operator` - (Required) The operator for a given condition. Possible values are `Equals`, `NotEquals`, `Contains`, and `DoesNotContain`. * `values` - (Required) A list of values to match for a given condition. @@ -199,7 +128,7 @@ The `alert_context` block supports the following: The `alert_rule_id` block supports the following: -* `operator` - (Required) operator for a given condition. Possible values are `Equals`, `NotEquals`, `Contains` and `DoesNotContain`. +* `operator` - (Required) The operator for a given condition. Possible values are `Equals`, `NotEquals`, `Contains`, and `DoesNotContain`. * `values` - (Required) A list of values to match for a given condition. @@ -207,7 +136,7 @@ The `alert_rule_id` block supports the following: The `description` block supports the following: -* `operator` - (Required) operator for a given condition. Possible values are `Equals`, `NotEquals`, `Contains` and `DoesNotContain`. +* `operator` - (Required) The operator for a given condition. Possible values are `Equals`, `NotEquals`, `Contains`, and `DoesNotContain`. * `values` - (Required) A list of values to match for a given condition. @@ -215,33 +144,33 @@ The `description` block supports the following: The `monitor` block supports the following: -* `operator` - (Required) operator for a given condition. Possible values are `Equals`, `NotEquals`. +* `operator` - (Required) The operator for a given condition. Possible values are `Equals` and `NotEquals`. -* `values` - (Required) A list of values to match for a given condition. Possible values are `Fired`, `Resolved`. +* `values` - (Required) A list of values to match for a given condition. Possible values are `Fired` and `Resolved`. --- The `monitor_service` block supports the following: -* `operator` - (Required) operator for a given condition. Possible values are `Equals`, `NotEquals`. +* `operator` - (Required) The operator for a given condition. Possible values are `Equals` and `NotEquals`. -* `values` - (Required) A list of values to match for a given condition. Possible values are `ActivityLog Administrative`, `ActivityLog Autoscale`, `ActivityLog Policy`, `ActivityLog Recommendation`, `ActivityLog Security`, `Application Insights`, `Azure Backup`, `Data Box Edge`, `Data Box Gateway`, `Health Platform`, `Log Analytics`, `Platform` and `Resource Health`. +* `values` - (Required) A list of values to match for a given condition. Possible values are `ActivityLog Administrative`, `ActivityLog Autoscale`, `ActivityLog Policy`, `ActivityLog Recommendation`, `ActivityLog Security`, `Application Insights`, `Azure Backup`, `Data Box Edge`, `Data Box Gateway`, `Health Platform`, `Log Analytics`, `Platform`, and `Resource Health`. --- The `severity` block supports the following: -* `operator` - (Required) operator for a given condition. Possible values are `Equals`, `NotEquals`. +* `operator` - (Required) The operator for a given condition. Possible values are `Equals`and `NotEquals`. -* `values` - (Required) A list of values to match for a given condition. Possible values are `Sev0`, `Sev1`, `Sev2`, `Sev3` and `Sev4`. +* `values` - (Required) A list of values to match for a given condition. Possible values are `Sev0`, `Sev1`, `Sev2`, `Sev3`, and `Sev4`. --- The `target_resource_type` block supports the following: -* `operator` - (Required) operator for a given condition. Possible values are `Equals`, `NotEquals`. +* `operator` - (Required) The operator for a given condition. Possible values are `Equals` and `NotEquals`. -* `values` - (Required) list of values to match for a given condition. The values should be valid resource types. +* `values` - (Required) A list of values to match for a given condition. The values should be valid resource types. --- @@ -265,5 +194,5 @@ The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/d Monitor Action Rule can be imported using the `resource id`, e.g. ```shell -$ terraform import azurerm_monitor_action_rule.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.AlertsManagement/actionRules/actionRule1 +$ terraform import azurerm_monitor_action_rule_suppression.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.AlertsManagement/actionRules/actionRule1 ```