diff --git a/azurerm/internal/services/applicationinsights/application_insights_smart_detection_rule_resource.go b/azurerm/internal/services/applicationinsights/application_insights_smart_detection_rule_resource.go new file mode 100644 index 000000000000..9eb80d5e51de --- /dev/null +++ b/azurerm/internal/services/applicationinsights/application_insights_smart_detection_rule_resource.go @@ -0,0 +1,186 @@ +package applicationinsights + +import ( + "fmt" + "log" + "strings" + "time" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/applicationinsights/parse" + + "github.com/Azure/azure-sdk-for-go/services/appinsights/mgmt/2015-05-01/insights" + "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/internal/clients" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceApplicationInsightsSmartDetectionRule() *schema.Resource { + return &schema.Resource{ + Create: resourceApplicationInsightsSmartDetectionRuleUpdate, + Read: resourceApplicationInsightsSmartDetectionRuleRead, + Update: resourceApplicationInsightsSmartDetectionRuleUpdate, + Delete: resourceApplicationInsightsSmartDetectionRuleDelete, + + 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), + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{ + "Slow page load time", + "Slow server response time", + "Long dependency duration", + }, false), + DiffSuppressFunc: smartDetectionRuleNameDiff, + }, + + "application_insights_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateResourceID, + }, + + "enabled": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + + "send_emails_to_subscription_owners": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + + "additional_email_recipients": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + } +} + +func resourceApplicationInsightsSmartDetectionRuleUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).AppInsights.SmartDetectionRuleClient + ctx, cancel := timeouts.ForCreate(meta.(*clients.Client).StopContext, d) + defer cancel() + + log.Printf("[INFO] preparing arguments for AzureRM Application Insights Samrt Detection Rule update.") + + // The Smart Detection Rule name from the UI doesn't match what the API accepts. + // We'll have the user submit what the name looks like in the UI and trim it behind the scenes to match what the API accepts + name := strings.ToLower(strings.Join(strings.Split(d.Get("name").(string), " "), "")) + appInsightsID := d.Get("application_insights_id").(string) + + id, err := parse.ComponentID(appInsightsID) + if err != nil { + return err + } + + smartDetectionRuleProperties := insights.ApplicationInsightsComponentProactiveDetectionConfiguration{ + Name: &name, + Enabled: utils.Bool(d.Get("enabled").(bool)), + SendEmailsToSubscriptionOwners: utils.Bool(d.Get("send_emails_to_subscription_owners").(bool)), + CustomEmails: utils.ExpandStringSlice(d.Get("additional_email_recipients").(*schema.Set).List()), + } + + _, err = client.Update(ctx, id.ResourceGroup, id.Name, name, smartDetectionRuleProperties) + if err != nil { + return fmt.Errorf("updating Application Insights Smart Detection Rule %q (Application Insights %q): %+v", name, id.String(), err) + } + + d.SetId(fmt.Sprintf("%s/SmartDetectionRule/%s", id.ID(), name)) + + return resourceApplicationInsightsSmartDetectionRuleRead(d, meta) +} + +func resourceApplicationInsightsSmartDetectionRuleRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).AppInsights.SmartDetectionRuleClient + ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) + defer cancel() + + id, err := parse.SmartDetectionRuleID(d.Id()) + if err != nil { + return err + } + + log.Printf("[DEBUG] Reading AzureRM Application Insights Smart Detection Rule %q", id.String()) + + result, err := client.Get(ctx, id.ResourceGroup, id.ComponentName, id.SmartDetectionRuleName) + if err != nil { + if utils.ResponseWasNotFound(result.Response) { + log.Printf("[WARN] AzureRM Application Insights Smart Detection Rule %q not found, removing from state", id.String()) + d.SetId("") + return nil + } + return fmt.Errorf("making Read request on AzureRM Application Insights Smart Detection Rule %q: %+v", id.String(), err) + } + + d.Set("name", result.Name) + d.Set("application_insights_id", parse.NewComponentID(id.SubscriptionId, id.ResourceGroup, id.ComponentName).ID()) + d.Set("enabled", result.Enabled) + d.Set("send_emails_to_subscription_owners", result.SendEmailsToSubscriptionOwners) + d.Set("additional_email_recipients", utils.FlattenStringSlice(result.CustomEmails)) + return nil +} + +func resourceApplicationInsightsSmartDetectionRuleDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).AppInsights.SmartDetectionRuleClient + ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d) + defer cancel() + + id, err := parse.SmartDetectionRuleID(d.Id()) + if err != nil { + return err + } + + log.Printf("[DEBUG] reseting AzureRM Application Insights Smart Detection Rule %q", id.String()) + + result, err := client.Get(ctx, id.ResourceGroup, id.ComponentName, id.SmartDetectionRuleName) + if err != nil { + if utils.ResponseWasNotFound(result.Response) { + log.Printf("[WARN] AzureRM Application Insights Smart Detection Rule %q not found, removing from state", id.String()) + d.SetId("") + return nil + } + return fmt.Errorf("making Read request on AzureRM Application Insights Smart Detection Rule %q: %+v", id.String(), err) + } + + smartDetectionRuleProperties := insights.ApplicationInsightsComponentProactiveDetectionConfiguration{ + Name: utils.String(id.SmartDetectionRuleName), + Enabled: result.RuleDefinitions.IsEnabledByDefault, + SendEmailsToSubscriptionOwners: result.RuleDefinitions.SupportsEmailNotifications, + CustomEmails: utils.ExpandStringSlice([]interface{}{}), + } + + // Application Insights defaults all the Smart Detection Rules so if a user wants to delete a rule, we'll update it back to it's default values. + _, err = client.Update(ctx, id.ResourceGroup, id.ComponentName, id.SmartDetectionRuleName, smartDetectionRuleProperties) + if err != nil { + if utils.ResponseWasNotFound(result.Response) { + return nil + } + return fmt.Errorf("issuing AzureRM reset update request for Application Insights Smart Detection Rule %q: %+v", id.String(), err) + } + + return nil +} + +// The Smart Detection Rule name from the UI doesn't match what the API accepts. +// This Diff checks that the name UI name matches the API name when spaces are removed +func smartDetectionRuleNameDiff(_, old string, new string, _ *schema.ResourceData) bool { + trimmedNew := strings.Join(strings.Split(strings.ToLower(new), " "), "") + + return strings.EqualFold(old, trimmedNew) +} diff --git a/azurerm/internal/services/applicationinsights/application_insights_smart_detection_rule_resource_test.go b/azurerm/internal/services/applicationinsights/application_insights_smart_detection_rule_resource_test.go new file mode 100644 index 000000000000..60697026e0a2 --- /dev/null +++ b/azurerm/internal/services/applicationinsights/application_insights_smart_detection_rule_resource_test.go @@ -0,0 +1,216 @@ +package applicationinsights_test + +import ( + "context" + "fmt" + "net/http" + "testing" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/applicationinsights/parse" + + "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/acceptance/check" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +type AppInsightsSmartDetectionRule struct { +} + +func TestAccApplicationInsightsSmartDetectionRule_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_application_insights_smart_detection_rule", "test") + r := AppInsightsSmartDetectionRule{} + + data.ResourceTest(t, r, []resource.TestStep{ + { + Config: r.basic(data), + Check: resource.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + }) +} + +func TestAccApplicationInsightsSmartDetectionRule_update(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_application_insights_smart_detection_rule", "test") + r := AppInsightsSmartDetectionRule{} + + data.ResourceTest(t, r, []resource.TestStep{ + { + Config: r.basic(data), + Check: resource.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + { + Config: r.update(data), + Check: resource.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + { + Config: r.basic(data), + Check: resource.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + }) +} + +func TestAccApplicationInsightsSmartDetectionRule_multiple(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_application_insights_smart_detection_rule", "test") + r := AppInsightsSmartDetectionRule{} + + data.ResourceTest(t, r, []resource.TestStep{ + { + Config: r.multiple(data), + Check: resource.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That("azurerm_application_insights_smart_detection_rule.test2").ExistsInAzure(r), + ), + }, + }) +} + +func TestAccApplicationInsightsSmartDetectionRule_longDependencyDuration(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_application_insights_smart_detection_rule", "test") + r := AppInsightsSmartDetectionRule{} + + data.ResourceTest(t, r, []resource.TestStep{ + { + Config: r.longDependencyDuration(data), + Check: resource.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + }) +} + +func (t AppInsightsSmartDetectionRule) Exists(ctx context.Context, clients *clients.Client, state *terraform.InstanceState) (*bool, error) { + id, err := parse.SmartDetectionRuleID(state.Attributes["id"]) + if err != nil { + return nil, err + } + + resp, err := clients.AppInsights.SmartDetectionRuleClient.Get(ctx, id.ResourceGroup, id.ComponentName, id.SmartDetectionRuleName) + if err != nil { + return nil, fmt.Errorf("retrieving Application Insights Smart Detection Rule '%q' does not exist", id.String()) + } + + return utils.Bool(resp.StatusCode != http.StatusNotFound), nil +} + +func (AppInsightsSmartDetectionRule) basic(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_application_insights" "test" { + name = "acctestappinsights-%d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + application_type = "web" +} + +resource "azurerm_application_insights_smart_detection_rule" "test" { + name = "Slow page load time" + application_insights_id = azurerm_application_insights.test.id + enabled = false +} +`, data.RandomInteger, data.Locations.Primary, data.RandomInteger) +} + +func (AppInsightsSmartDetectionRule) update(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_application_insights" "test" { + name = "acctestappinsights-%d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + application_type = "web" +} + +resource "azurerm_application_insights_smart_detection_rule" "test" { + name = "Slow page load time" + application_insights_id = azurerm_application_insights.test.id + enabled = false + + send_emails_to_subscription_owners = false + additional_email_recipients = ["test@example.com", "test2@example.com"] +} +`, data.RandomInteger, data.Locations.Primary, data.RandomInteger) +} + +func (AppInsightsSmartDetectionRule) multiple(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_application_insights" "test" { + name = "acctestappinsights-%d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + application_type = "web" +} + +resource "azurerm_application_insights_smart_detection_rule" "test" { + name = "Slow page load time" + application_insights_id = azurerm_application_insights.test.id + enabled = false +} + +resource "azurerm_application_insights_smart_detection_rule" "test2" { + name = "Slow server response time" + application_insights_id = azurerm_application_insights.test.id + enabled = false +} +`, data.RandomInteger, data.Locations.Primary, data.RandomInteger) +} + +func (AppInsightsSmartDetectionRule) longDependencyDuration(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_application_insights" "test" { + name = "acctestappinsights-%d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + application_type = "web" +} + +resource "azurerm_application_insights_smart_detection_rule" "test" { + name = "Long dependency duration" + application_insights_id = azurerm_application_insights.test.id + enabled = false +} +`, data.RandomInteger, data.Locations.Primary, data.RandomInteger) +} diff --git a/azurerm/internal/services/applicationinsights/client/client.go b/azurerm/internal/services/applicationinsights/client/client.go index 17d8bf3fd68a..f4907452f511 100644 --- a/azurerm/internal/services/applicationinsights/client/client.go +++ b/azurerm/internal/services/applicationinsights/client/client.go @@ -6,11 +6,12 @@ import ( ) type Client struct { - AnalyticsItemsClient *insights.AnalyticsItemsClient - APIKeysClient *insights.APIKeysClient - ComponentsClient *insights.ComponentsClient - WebTestsClient *insights.WebTestsClient - BillingClient *insights.ComponentCurrentBillingFeaturesClient + AnalyticsItemsClient *insights.AnalyticsItemsClient + APIKeysClient *insights.APIKeysClient + ComponentsClient *insights.ComponentsClient + WebTestsClient *insights.WebTestsClient + BillingClient *insights.ComponentCurrentBillingFeaturesClient + SmartDetectionRuleClient *insights.ProactiveDetectionConfigurationsClient } func NewClient(o *common.ClientOptions) *Client { @@ -29,11 +30,15 @@ func NewClient(o *common.ClientOptions) *Client { billingClient := insights.NewComponentCurrentBillingFeaturesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) o.ConfigureClient(&billingClient.Client, o.ResourceManagerAuthorizer) + smartDetectionRuleClient := insights.NewProactiveDetectionConfigurationsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&smartDetectionRuleClient.Client, o.ResourceManagerAuthorizer) + return &Client{ - AnalyticsItemsClient: &analyticsItemsClient, - APIKeysClient: &apiKeysClient, - ComponentsClient: &componentsClient, - WebTestsClient: &webTestsClient, - BillingClient: &billingClient, + AnalyticsItemsClient: &analyticsItemsClient, + APIKeysClient: &apiKeysClient, + ComponentsClient: &componentsClient, + WebTestsClient: &webTestsClient, + BillingClient: &billingClient, + SmartDetectionRuleClient: &smartDetectionRuleClient, } } diff --git a/azurerm/internal/services/applicationinsights/parse/smart_detection_rule.go b/azurerm/internal/services/applicationinsights/parse/smart_detection_rule.go new file mode 100644 index 000000000000..744d5c81586b --- /dev/null +++ b/azurerm/internal/services/applicationinsights/parse/smart_detection_rule.go @@ -0,0 +1,75 @@ +package parse + +// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten + +import ( + "fmt" + "strings" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" +) + +type SmartDetectionRuleId struct { + SubscriptionId string + ResourceGroup string + ComponentName string + SmartDetectionRuleName string +} + +func NewSmartDetectionRuleID(subscriptionId, resourceGroup, componentName, smartDetectionRuleName string) SmartDetectionRuleId { + return SmartDetectionRuleId{ + SubscriptionId: subscriptionId, + ResourceGroup: resourceGroup, + ComponentName: componentName, + SmartDetectionRuleName: smartDetectionRuleName, + } +} + +func (id SmartDetectionRuleId) String() string { + segments := []string{ + fmt.Sprintf("Smart Detection Rule Name %q", id.SmartDetectionRuleName), + fmt.Sprintf("Component Name %q", id.ComponentName), + fmt.Sprintf("Resource Group %q", id.ResourceGroup), + } + segmentsStr := strings.Join(segments, " / ") + return fmt.Sprintf("%s: (%s)", "Smart Detection Rule", segmentsStr) +} + +func (id SmartDetectionRuleId) ID() string { + fmtString := "/subscriptions/%s/resourceGroups/%s/providers/microsoft.insights/components/%s/SmartDetectionRule/%s" + return fmt.Sprintf(fmtString, id.SubscriptionId, id.ResourceGroup, id.ComponentName, id.SmartDetectionRuleName) +} + +// SmartDetectionRuleID parses a SmartDetectionRule ID into an SmartDetectionRuleId struct +func SmartDetectionRuleID(input string) (*SmartDetectionRuleId, error) { + id, err := azure.ParseAzureResourceID(input) + if err != nil { + return nil, err + } + + resourceId := SmartDetectionRuleId{ + SubscriptionId: id.SubscriptionID, + ResourceGroup: id.ResourceGroup, + } + + if resourceId.SubscriptionId == "" { + return nil, fmt.Errorf("ID was missing the 'subscriptions' element") + } + + if resourceId.ResourceGroup == "" { + return nil, fmt.Errorf("ID was missing the 'resourceGroups' element") + } + + if resourceId.ComponentName, err = id.PopSegment("components"); err != nil { + return nil, err + } + if resourceId.SmartDetectionRuleName, err = id.PopSegment("SmartDetectionRule"); err != nil { + return nil, err + } + + if err := id.ValidateNoEmptySegments(input); err != nil { + return nil, err + } + + return &resourceId, nil +} diff --git a/azurerm/internal/services/applicationinsights/parse/smart_detection_rule_test.go b/azurerm/internal/services/applicationinsights/parse/smart_detection_rule_test.go new file mode 100644 index 000000000000..d44439d84ca6 --- /dev/null +++ b/azurerm/internal/services/applicationinsights/parse/smart_detection_rule_test.go @@ -0,0 +1,128 @@ +package parse + +// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten + +import ( + "testing" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/resourceid" +) + +var _ resourceid.Formatter = SmartDetectionRuleId{} + +func TestSmartDetectionRuleIDFormatter(t *testing.T) { + actual := NewSmartDetectionRuleID("12345678-1234-9876-4563-123456789012", "group1", "component1", "rule1").ID() + expected := "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/group1/providers/microsoft.insights/components/component1/SmartDetectionRule/rule1" + if actual != expected { + t.Fatalf("Expected %q but got %q", expected, actual) + } +} + +func TestSmartDetectionRuleID(t *testing.T) { + testData := []struct { + Input string + Error bool + Expected *SmartDetectionRuleId + }{ + + { + // empty + Input: "", + Error: true, + }, + + { + // missing SubscriptionId + Input: "/", + Error: true, + }, + + { + // missing value for SubscriptionId + Input: "/subscriptions/", + Error: true, + }, + + { + // missing ResourceGroup + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/", + Error: true, + }, + + { + // missing value for ResourceGroup + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/", + Error: true, + }, + + { + // missing ComponentName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/group1/providers/microsoft.insights/", + Error: true, + }, + + { + // missing value for ComponentName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/group1/providers/microsoft.insights/components/", + Error: true, + }, + + { + // missing SmartDetectionRuleName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/group1/providers/microsoft.insights/components/component1/", + Error: true, + }, + + { + // missing value for SmartDetectionRuleName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/group1/providers/microsoft.insights/components/component1/SmartDetectionRule/", + Error: true, + }, + + { + // valid + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/group1/providers/microsoft.insights/components/component1/SmartDetectionRule/rule1", + Expected: &SmartDetectionRuleId{ + SubscriptionId: "12345678-1234-9876-4563-123456789012", + ResourceGroup: "group1", + ComponentName: "component1", + SmartDetectionRuleName: "rule1", + }, + }, + + { + // upper-cased + Input: "/SUBSCRIPTIONS/12345678-1234-9876-4563-123456789012/RESOURCEGROUPS/GROUP1/PROVIDERS/MICROSOFT.INSIGHTS/COMPONENTS/COMPONENT1/SMARTDETECTIONRULE/RULE1", + Error: true, + }, + } + + for _, v := range testData { + t.Logf("[DEBUG] Testing %q", v.Input) + + actual, err := SmartDetectionRuleID(v.Input) + if err != nil { + if v.Error { + continue + } + + t.Fatalf("Expect a value but got an error: %s", err) + } + if v.Error { + t.Fatal("Expect an error but didn't get one") + } + + if actual.SubscriptionId != v.Expected.SubscriptionId { + t.Fatalf("Expected %q but got %q for SubscriptionId", v.Expected.SubscriptionId, actual.SubscriptionId) + } + if actual.ResourceGroup != v.Expected.ResourceGroup { + t.Fatalf("Expected %q but got %q for ResourceGroup", v.Expected.ResourceGroup, actual.ResourceGroup) + } + if actual.ComponentName != v.Expected.ComponentName { + t.Fatalf("Expected %q but got %q for ComponentName", v.Expected.ComponentName, actual.ComponentName) + } + if actual.SmartDetectionRuleName != v.Expected.SmartDetectionRuleName { + t.Fatalf("Expected %q but got %q for SmartDetectionRuleName", v.Expected.SmartDetectionRuleName, actual.SmartDetectionRuleName) + } + } +} diff --git a/azurerm/internal/services/applicationinsights/registration.go b/azurerm/internal/services/applicationinsights/registration.go index 6b4f385236be..1deb2cc9fb77 100644 --- a/azurerm/internal/services/applicationinsights/registration.go +++ b/azurerm/internal/services/applicationinsights/registration.go @@ -28,9 +28,10 @@ func (r Registration) SupportedDataSources() map[string]*schema.Resource { // SupportedResources returns the supported Resources supported by this Service func (r Registration) SupportedResources() map[string]*schema.Resource { return map[string]*schema.Resource{ - "azurerm_application_insights_api_key": resourceApplicationInsightsAPIKey(), - "azurerm_application_insights": resourceApplicationInsights(), - "azurerm_application_insights_analytics_item": resourceApplicationInsightsAnalyticsItem(), - "azurerm_application_insights_web_test": resourceApplicationInsightsWebTests(), + "azurerm_application_insights_api_key": resourceApplicationInsightsAPIKey(), + "azurerm_application_insights": resourceApplicationInsights(), + "azurerm_application_insights_analytics_item": resourceApplicationInsightsAnalyticsItem(), + "azurerm_application_insights_smart_detection_rule": resourceApplicationInsightsSmartDetectionRule(), + "azurerm_application_insights_web_test": resourceApplicationInsightsWebTests(), } } diff --git a/azurerm/internal/services/applicationinsights/resourceids.go b/azurerm/internal/services/applicationinsights/resourceids.go index b184c6025654..c6b16507177f 100644 --- a/azurerm/internal/services/applicationinsights/resourceids.go +++ b/azurerm/internal/services/applicationinsights/resourceids.go @@ -1,4 +1,5 @@ package applicationinsights //go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=Component -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/group1/providers/microsoft.insights/components/component1 +//go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=SmartDetectionRule -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/group1/providers/microsoft.insights/components/component1/SmartDetectionRule/rule1 //go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=WebTest -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/group1/providers/microsoft.insights/webtests/test1 diff --git a/azurerm/internal/services/applicationinsights/validate/smart_detection_rule_id.go b/azurerm/internal/services/applicationinsights/validate/smart_detection_rule_id.go new file mode 100644 index 000000000000..55037d933f9a --- /dev/null +++ b/azurerm/internal/services/applicationinsights/validate/smart_detection_rule_id.go @@ -0,0 +1,23 @@ +package validate + +// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten + +import ( + "fmt" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/applicationinsights/parse" +) + +func SmartDetectionRuleID(input interface{}, key string) (warnings []string, errors []error) { + v, ok := input.(string) + if !ok { + errors = append(errors, fmt.Errorf("expected %q to be a string", key)) + return + } + + if _, err := parse.SmartDetectionRuleID(v); err != nil { + errors = append(errors, err) + } + + return +} diff --git a/azurerm/internal/services/applicationinsights/validate/smart_detection_rule_id_test.go b/azurerm/internal/services/applicationinsights/validate/smart_detection_rule_id_test.go new file mode 100644 index 000000000000..a6ff27df0180 --- /dev/null +++ b/azurerm/internal/services/applicationinsights/validate/smart_detection_rule_id_test.go @@ -0,0 +1,88 @@ +package validate + +// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten + +import "testing" + +func TestSmartDetectionRuleID(t *testing.T) { + cases := []struct { + Input string + Valid bool + }{ + + { + // empty + Input: "", + Valid: false, + }, + + { + // missing SubscriptionId + Input: "/", + Valid: false, + }, + + { + // missing value for SubscriptionId + Input: "/subscriptions/", + Valid: false, + }, + + { + // missing ResourceGroup + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/", + Valid: false, + }, + + { + // missing value for ResourceGroup + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/", + Valid: false, + }, + + { + // missing ComponentName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/group1/providers/microsoft.insights/", + Valid: false, + }, + + { + // missing value for ComponentName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/group1/providers/microsoft.insights/components/", + Valid: false, + }, + + { + // missing SmartDetectionRuleName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/group1/providers/microsoft.insights/components/component1/", + Valid: false, + }, + + { + // missing value for SmartDetectionRuleName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/group1/providers/microsoft.insights/components/component1/SmartDetectionRule/", + Valid: false, + }, + + { + // valid + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/group1/providers/microsoft.insights/components/component1/SmartDetectionRule/rule1", + Valid: true, + }, + + { + // upper-cased + Input: "/SUBSCRIPTIONS/12345678-1234-9876-4563-123456789012/RESOURCEGROUPS/GROUP1/PROVIDERS/MICROSOFT.INSIGHTS/COMPONENTS/COMPONENT1/SMARTDETECTIONRULE/RULE1", + Valid: false, + }, + } + for _, tc := range cases { + t.Logf("[DEBUG] Testing Value %s", tc.Input) + _, errors := SmartDetectionRuleID(tc.Input, "test") + valid := len(errors) == 0 + + if tc.Valid != valid { + t.Fatalf("Expected %t but got %t", tc.Valid, valid) + } + } +} diff --git a/website/azurerm.erb b/website/azurerm.erb index b6e0ef1dc51d..e46cb37bb0b9 100644 --- a/website/azurerm.erb +++ b/website/azurerm.erb @@ -952,11 +952,14 @@ azurerm_application_insights_api_key -
  • azurerm_application_insights_analytics_item
  • +
  • + application_insights_smart_detection_rule +
  • +
  • azurerm_application_insights_web_test
  • diff --git a/website/docs/r/application_insights_smart_detection_rule.html.markdown b/website/docs/r/application_insights_smart_detection_rule.html.markdown new file mode 100644 index 000000000000..0ab5ad334b66 --- /dev/null +++ b/website/docs/r/application_insights_smart_detection_rule.html.markdown @@ -0,0 +1,65 @@ +--- +subcategory: "Application Insights" +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_application_insights_smart_detection_rule" +description: |- + Manages an Application Insights Smart Detection Rule. +--- + +# azurerm_application_insights_smart_detection_rule + +Manages an Application Insights Smart Detection Rule. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "tf-test" + location = "West Europe" +} + +resource "azurerm_application_insights" "example" { + name = "tf-test-appinsights" + location = "West Europe" + resource_group_name = azurerm_resource_group.example.name + application_type = "web" +} + +resource "azurerm_application_insights_smart_detection_rule" "example" { + name = "Slow server response time" + application_insights_id = azurerm_application_insights.example.id + enabled = false +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the Application Insights Smart Detection Rule. Valid values include `Slow page load time`, `Slow server response time`, +`Long dependency duration`. Changing this forces a new resource to be created. + +* `application_insights_id` - (Required) The ID of the Application Insights component on which the Smart Detection Rule operates. Changing this forces a new resource to be created. + +* `enabled` - (Optional) Is the Application Insights Smart Detection Rule enabled? Defaults to `true`. + +* `send_emails_to_subscription_owners` - (Optional) Do emails get sent to subscription owners? Defaults to `true`. + +* `additional_email_recipients` - (Optional) Specifies a list of additional recipients that will be sent emails on this Application Insights Smart Detection Rule. + +-> **Note:** At least one read or write permission must be defined. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the Application Insights Smart Detection 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 Application Insights Smart Detection Rule +* `update` - (Defaults to 30 minutes) Used when updating the Application Insights Smart Detection Rule. +* `read` - (Defaults to 5 minutes) Used when retrieving the Application Insights Smart Detection Rule. +* `delete` - (Defaults to 30 minutes) Used when deleting the Application Insights Smart Detection Rule.