From 47d9a22acca401d244b4ddd2d1af5b8dbb1c7a55 Mon Sep 17 00:00:00 2001 From: Patrick Decat Date: Thu, 20 Dec 2018 12:12:00 +0100 Subject: [PATCH 01/17] Add azurerm_application_insights_api_key resource --- azurerm/config.go | 7 +- azurerm/helpers/azure/app_insights.go | 35 +++ azurerm/helpers/validate/strings.go | 14 + azurerm/provider.go | 1 + ...source_arm_application_insights_api_key.go | 179 +++++++++++ ...e_arm_application_insights_api_key_test.go | 287 ++++++++++++++++++ 6 files changed, 522 insertions(+), 1 deletion(-) create mode 100644 azurerm/helpers/azure/app_insights.go create mode 100644 azurerm/resource_arm_application_insights_api_key.go create mode 100644 azurerm/resource_arm_application_insights_api_key_test.go diff --git a/azurerm/config.go b/azurerm/config.go index e0be1bc82b1a..e3bc57594014 100644 --- a/azurerm/config.go +++ b/azurerm/config.go @@ -126,7 +126,8 @@ type ArmClient struct { apiManagementServiceClient apimanagement.ServiceClient // Application Insights - appInsightsClient appinsights.ComponentsClient + appInsightsClient appinsights.ComponentsClient + appInsightsAPIKeyClient appinsights.APIKeysClient // Authentication roleAssignmentsClient authorization.RoleAssignmentsClient @@ -480,6 +481,10 @@ func (c *ArmClient) registerAppInsightsClients(endpoint, subscriptionId string, ai := appinsights.NewComponentsClientWithBaseURI(endpoint, subscriptionId) c.configureClient(&ai.Client, auth) c.appInsightsClient = ai + + aiak := appinsights.NewAPIKeysClientWithBaseURI(endpoint, subscriptionId) + c.configureClient(&aiak.Client, auth) + c.appInsightsAPIKeyClient = aiak } func (c *ArmClient) registerAutomationClients(endpoint, subscriptionId string, auth autorest.Authorizer) { diff --git a/azurerm/helpers/azure/app_insights.go b/azurerm/helpers/azure/app_insights.go new file mode 100644 index 000000000000..94726b781a00 --- /dev/null +++ b/azurerm/helpers/azure/app_insights.go @@ -0,0 +1,35 @@ +package azure + +import ( + "fmt" + "strings" + + "github.com/hashicorp/terraform/helper/schema" +) + +func ExpandApplicationInsightsAPIKeyLinkedProperties(v *schema.Set, subscriptionID, resGroup, appInsightsName string) *[]string { + if v == nil { + return nil + } + + baseLinkedProperty := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/microsoft.insights/components/%s", subscriptionID, resGroup, appInsightsName) + + result := make([]string, v.Len()) + for i, prop := range v.List() { + result[i] = fmt.Sprintf("%s/%s", baseLinkedProperty, prop) + } + return &result +} + +func FlattenApplicationInsightsAPIKeyLinkedProperties(props *[]string) *[]string { + if props == nil { + return nil + } + + result := make([]string, len(*props)) + for i, prop := range *props { + elems := strings.Split(prop, "/") + result[i] = elems[len(elems)-1] + } + return &result +} diff --git a/azurerm/helpers/validate/strings.go b/azurerm/helpers/validate/strings.go index 1dec1bd2e07f..2c8b6bd2c7b8 100644 --- a/azurerm/helpers/validate/strings.go +++ b/azurerm/helpers/validate/strings.go @@ -18,3 +18,17 @@ func NoEmptyStrings(i interface{}, k string) ([]string, []error) { return nil, nil } + +// LowercaseString validates that the string is all lower case characters +func LowercaseString(i interface{}, k string) ([]string, []error) { + v, ok := i.(string) + if !ok { + return nil, []error{fmt.Errorf("expected type of %q to be string", k)} + } + + if v != strings.ToLower(v) { + return nil, []error{fmt.Errorf("%q must not be lower case", k)} + } + + return nil, nil +} diff --git a/azurerm/provider.go b/azurerm/provider.go index 8adc25472d8c..567dd7108f08 100644 --- a/azurerm/provider.go +++ b/azurerm/provider.go @@ -152,6 +152,7 @@ func Provider() terraform.ResourceProvider { "azurerm_api_management": resourceArmApiManagementService(), "azurerm_application_gateway": resourceArmApplicationGateway(), "azurerm_application_insights": resourceArmApplicationInsights(), + "azurerm_application_insights_api_key": resourceArmApplicationInsightsAPIKey(), "azurerm_application_security_group": resourceArmApplicationSecurityGroup(), "azurerm_app_service": resourceArmAppService(), "azurerm_app_service_plan": resourceArmAppServicePlan(), diff --git a/azurerm/resource_arm_application_insights_api_key.go b/azurerm/resource_arm_application_insights_api_key.go new file mode 100644 index 000000000000..9d2212a77077 --- /dev/null +++ b/azurerm/resource_arm_application_insights_api_key.go @@ -0,0 +1,179 @@ +package azurerm + +import ( + "fmt" + "log" + "net/http" + + "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/helpers/validate" + + "github.com/Azure/azure-sdk-for-go/services/appinsights/mgmt/2015-05-01/insights" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmApplicationInsightsAPIKey() *schema.Resource { + return &schema.Resource{ + Create: resourceArmApplicationInsightsAPIKeyCreate, + Read: resourceArmApplicationInsightsAPIKeyRead, + Delete: resourceArmApplicationInsightsAPIKeyDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "api_key": { + Type: schema.TypeString, + Computed: true, + Sensitive: true, + }, + + "application_insights_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "resource_group_name": resourceGroupNameSchema(), + + "read_permissions": { + Type: schema.TypeSet, + Optional: true, + ForceNew: true, + Set: schema.HashString, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validate.LowercaseString, + }, + }, + + "write_permissions": { + Type: schema.TypeSet, + Optional: true, + ForceNew: true, + Set: schema.HashString, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validate.LowercaseString, + }, + }, + }, + } +} + +func resourceArmApplicationInsightsAPIKeyCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).appInsightsAPIKeyClient + ctx := meta.(*ArmClient).StopContext + + log.Printf("[INFO] preparing arguments for AzureRM Application Insights API key creation.") + + name := d.Get("name").(string) + resGroup := d.Get("resource_group_name").(string) + appInsightsName := d.Get("application_insights_name").(string) + + if requireResourcesToBeImported && d.IsNewResource() { + existing, err := client.Get(ctx, resGroup, appInsightsName, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing Application Insights API key %q (Resource Group %q): %s", name, resGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_application_insights_api_key", *existing.ID) + } + } + + apiKeyProperties := insights.APIKeyRequest{ + Name: &name, + LinkedReadProperties: azure.ExpandApplicationInsightsAPIKeyLinkedProperties(d.Get("read_permissions").(*schema.Set), client.SubscriptionID, resGroup, appInsightsName), + LinkedWriteProperties: azure.ExpandApplicationInsightsAPIKeyLinkedProperties(d.Get("write_permissions").(*schema.Set), client.SubscriptionID, resGroup, appInsightsName), + } + + result, err := client.Create(ctx, resGroup, appInsightsName, apiKeyProperties) + if err != nil { + return fmt.Errorf("Error creating Application Insights API key %q (Resource Group %q): %+v", name, resGroup, err) + } + + if result.Response.StatusCode != http.StatusOK { + return fmt.Errorf("Error creating Application Insights API key %q (Resource Group %q): %+v", name, resGroup, result.Response) + } + + if result.APIKey == nil { + return fmt.Errorf("Error creating Application Insights API key %q (Resource Group %q): got empty API key", name, resGroup) + } + + d.SetId(*result.ID) + + // API key can only retrieved at key creation + d.Set("api_key", result.APIKey) + + return resourceArmApplicationInsightsAPIKeyRead(d, meta) +} + +func resourceArmApplicationInsightsAPIKeyRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).appInsightsAPIKeyClient + ctx := meta.(*ArmClient).StopContext + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + + log.Printf("[DEBUG] Reading AzureRM Application Insights API key '%s'", id) + + resGroup := id.ResourceGroup + appInsightsName := id.Path["components"] + keyID := id.Path["apikeys"] + + resp, err := client.Get(ctx, resGroup, appInsightsName, keyID) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + return nil + } + return fmt.Errorf("Error making Read request on AzureRM Application Insights API key '%s': %+v", keyID, err) + } + + d.Set("resource_group_name", resGroup) + d.Set("application_insights_name", appInsightsName) + + d.Set("name", resp.Name) + d.Set("read_permissions", azure.FlattenApplicationInsightsAPIKeyLinkedProperties(resp.LinkedReadProperties)) + d.Set("write_permissions", azure.FlattenApplicationInsightsAPIKeyLinkedProperties(resp.LinkedWriteProperties)) + + return nil +} + +func resourceArmApplicationInsightsAPIKeyDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).appInsightsAPIKeyClient + ctx := meta.(*ArmClient).StopContext + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + resGroup := id.ResourceGroup + appInsightsName := id.Path["components"] + keyID := id.Path["apikeys"] + + log.Printf("[DEBUG] Deleting AzureRM Application Insights API key '%s' (resource group '%s')", keyID, resGroup) + + resp, err := client.Delete(ctx, resGroup, appInsightsName, keyID) + if err != nil { + if resp.StatusCode == http.StatusNotFound { + return nil + } + return fmt.Errorf("Error issuing AzureRM delete request for Application Insights API key '%s': %+v", keyID, err) + } + + return err +} diff --git a/azurerm/resource_arm_application_insights_api_key_test.go b/azurerm/resource_arm_application_insights_api_key_test.go new file mode 100644 index 000000000000..e5fd8810bc07 --- /dev/null +++ b/azurerm/resource_arm_application_insights_api_key_test.go @@ -0,0 +1,287 @@ +package azurerm + +import ( + "fmt" + "net/http" + "regexp" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccAzureRMApplicationInsightsAPIKey_no_permission(t *testing.T) { + ri := acctest.RandInt() + config := testAccAzureRMApplicationInsightsAPIKey_basic(ri, testLocation(), "[]", "[]") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApplicationInsightsAPIKeyDestroy, + Steps: []resource.TestStep{ + { + Config: config, + ExpectError: regexp.MustCompile("The API Key needs to have a Role"), + }, + }, + }) +} + +func TestAccAzureRMApplicationInsightsAPIKey_requiresImport(t *testing.T) { + if !requireResourcesToBeImported { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_application_insights_api_key.test" + ri := acctest.RandInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApplicationInsightsAPIKeyDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApplicationInsightsAPIKey_basic(ri, testLocation(), "[]", `["annotations"]`), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApplicationInsightsAPIKeyExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "read_permissions.#", "0"), + resource.TestCheckResourceAttr(resourceName, "write_permissions.#", "1"), + ), + }, + { + Config: testAccAzureRMApplicationInsightsAPIKey_requiresImport(ri, location, "[]", `["annotations"]`), + ExpectError: testRequiresImportError("azurerm_application_insights_api_key"), + }, + }, + }) +} + +func TestAccAzureRMApplicationInsightsAPIKey_read_telemetry_permissions(t *testing.T) { + resourceName := "azurerm_application_insights_api_key.test" + ri := acctest.RandInt() + config := testAccAzureRMApplicationInsightsAPIKey_basic(ri, testLocation(), `["aggregate", "api", "draft", "extendqueries", "search"]`, "[]") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApplicationInsightsAPIKeyDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApplicationInsightsAPIKeyExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "read_permissions.#", "5"), + resource.TestCheckResourceAttr(resourceName, "write_permissions.#", "0"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "api_key", // not returned from API, sensitive + }, + }, + }, + }) +} + +func TestAccAzureRMApplicationInsightsAPIKey_write_annotations_permission(t *testing.T) { + resourceName := "azurerm_application_insights_api_key.test" + ri := acctest.RandInt() + config := testAccAzureRMApplicationInsightsAPIKey_basic(ri, testLocation(), "[]", `["annotations"]`) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApplicationInsightsAPIKeyDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApplicationInsightsAPIKeyExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "read_permissions.#", "0"), + resource.TestCheckResourceAttr(resourceName, "write_permissions.#", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "api_key", // not returned from API, sensitive + }, + }, + }, + }) +} + +func TestAccAzureRMApplicationInsightsAPIKey_authenticate_permission(t *testing.T) { + resourceName := "azurerm_application_insights_api_key.test" + ri := acctest.RandInt() + config := testAccAzureRMApplicationInsightsAPIKey_basic(ri, testLocation(), `["agentconfig"]`, "[]") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApplicationInsightsAPIKeyDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApplicationInsightsAPIKeyExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "read_permissions.#", "1"), + resource.TestCheckResourceAttr(resourceName, "write_permissions.#", "0"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "api_key", // not returned from API, sensitive + }, + }, + }, + }) + +} + +func TestAccAzureRMApplicationInsightsAPIKey_full_permissions(t *testing.T) { + resourceName := "azurerm_application_insights_api_key.test" + ri := acctest.RandInt() + config := testAccAzureRMApplicationInsightsAPIKey_basic(ri, testLocation(), `["agentconfig", "aggregate", "api", "draft", "extendqueries", "search"]`, `["annotations"]`) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApplicationInsightsAPIKeyDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApplicationInsightsAPIKeyExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "read_permissions.#", "6"), + resource.TestCheckResourceAttr(resourceName, "write_permissions.#", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "api_key", // not returned from API, sensitive + }, + }, + }, + }) + +} + +func testCheckAzureRMApplicationInsightsAPIKeyDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*ArmClient).appInsightsAPIKeyClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_application_insights_api_key" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + appInsightsName := rs.Primary.Attributes["application_insights_name"] + + resp, err := conn.Get(ctx, resourceGroup, appInsightsName, name) + + if err != nil { + return nil + } + + if resp.StatusCode != http.StatusNotFound { + return fmt.Errorf("Application Insights API Key still exists:\n%#v", resp) + } + } + + return nil +} + +func testCheckAzureRMApplicationInsightsAPIKeyExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + id, err := parseAzureResourceID(rs.Primary.Attributes["id"]) + if err != nil { + return err + } + keyID := id.Path["APIKeys"] + + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for App Insights API Key: %s", name) + } + appInsightsName, hasAppInsightsName := rs.Primary.Attributes["application_insights_name"] + if !hasAppInsightsName { + return fmt.Errorf("Bad: no Application Insights resource found in state for App Insights API Key: %s", name) + } + + conn := testAccProvider.Meta().(*ArmClient).appInsightsAPIKeyClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := conn.Get(ctx, resourceGroup, appInsightsName, keyID) + if err != nil { + return fmt.Errorf("Bad: Get on appInsightsAPIKeyClient: %+v", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: Application Insights API Key '%q' (resource group: '%q') does not exist", name, resourceGroup) + } + + return nil + } +} + +func testAccAzureRMApplicationInsightsAPIKey_basic(rInt int, location, readPerms, writePerms string) string { + return fmt.Sprintf(` +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_api_key" "test" { + name = "acctestappinsightsapikey-%d" + application_insights_name = "${azurerm_application_insights.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + read_permissions = %s + write_permissions = %s +} +`, rInt, location, rInt, rInt, readPerms, writePerms) +} + +func testAccAzureRMApplicationInsightsAPIKey_requiresImport(rInt int, location, readPerms, writePerms string) string { + template := testAccAzureRMApplicationInsightsAPIKey_basic(rInt, location, readPerms, writePerms) + return fmt.Sprintf(` +%s + +resource "azurerm_application_insights_api_key" "import" { + name = "${azurerm_application_insights_api_key.test.name}" + application_insights_name = "${azurerm_application_insights_api_key.test.application_insights_name}" + resource_group_name = "${azurerm_application_insights_api_key.test.resource_group_name}" + read_permissions = "${azurerm_application_insights_api_key.test.read_permissions}" + write_permissions = "${azurerm_application_insights_api_key.test.write_permissions}" +} +`, template) +} From acda77430560355737fe99dc4e4e22ca1eb4d298 Mon Sep 17 00:00:00 2001 From: Tom Harvey Date: Fri, 21 Dec 2018 08:25:19 +0100 Subject: [PATCH 02/17] Return nil instead of err Co-Authored-By: pdecat --- azurerm/resource_arm_application_insights_api_key.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azurerm/resource_arm_application_insights_api_key.go b/azurerm/resource_arm_application_insights_api_key.go index 9d2212a77077..b75c60fee871 100644 --- a/azurerm/resource_arm_application_insights_api_key.go +++ b/azurerm/resource_arm_application_insights_api_key.go @@ -175,5 +175,5 @@ func resourceArmApplicationInsightsAPIKeyDelete(d *schema.ResourceData, meta int return fmt.Errorf("Error issuing AzureRM delete request for Application Insights API key '%s': %+v", keyID, err) } - return err + return nil } From ba3452a47f5d2d34fbf7faded9b40daf17c043cd Mon Sep 17 00:00:00 2001 From: Tom Harvey Date: Fri, 21 Dec 2018 11:11:49 +0100 Subject: [PATCH 03/17] Error check setting complex objects in state Co-Authored-By: pdecat --- azurerm/resource_arm_application_insights_api_key.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/azurerm/resource_arm_application_insights_api_key.go b/azurerm/resource_arm_application_insights_api_key.go index b75c60fee871..ee42ce5b36b5 100644 --- a/azurerm/resource_arm_application_insights_api_key.go +++ b/azurerm/resource_arm_application_insights_api_key.go @@ -147,8 +147,14 @@ func resourceArmApplicationInsightsAPIKeyRead(d *schema.ResourceData, meta inter d.Set("application_insights_name", appInsightsName) d.Set("name", resp.Name) - d.Set("read_permissions", azure.FlattenApplicationInsightsAPIKeyLinkedProperties(resp.LinkedReadProperties)) - d.Set("write_permissions", azure.FlattenApplicationInsightsAPIKeyLinkedProperties(resp.LinkedWriteProperties)) + readProps := azure.FlattenApplicationInsightsAPIKeyLinkedProperties(resp.LinkedReadProperties) + if err := d.Set("read_permissions", readProps); err != nil { + return fmt.Errorf("Error flattening `read_permissions `: %s", err) + } + writeProps := azure.FlattenApplicationInsightsAPIKeyLinkedProperties(resp.LinkedWriteProperties) + if err := d.Set("write_permissions", writeProps); err != nil { + return fmt.Errorf("Error flattening `write_permissions `: %s", err) + } return nil } From 2c4d544ef508cae0b2746ea21b0f6dc81d600930 Mon Sep 17 00:00:00 2001 From: Patrick Decat Date: Fri, 21 Dec 2018 12:27:44 +0100 Subject: [PATCH 04/17] Replace `resource_group_name` and `application_insights_name` fields by `application_insights_id` on `azurerm_application_insights_api_key` resource --- azurerm/helpers/azure/app_insights.go | 6 +-- ...source_arm_application_insights_api_key.go | 22 ++++++---- ...e_arm_application_insights_api_key_test.go | 43 ++++++++----------- 3 files changed, 34 insertions(+), 37 deletions(-) diff --git a/azurerm/helpers/azure/app_insights.go b/azurerm/helpers/azure/app_insights.go index 94726b781a00..3cc7833d77cc 100644 --- a/azurerm/helpers/azure/app_insights.go +++ b/azurerm/helpers/azure/app_insights.go @@ -7,16 +7,14 @@ import ( "github.com/hashicorp/terraform/helper/schema" ) -func ExpandApplicationInsightsAPIKeyLinkedProperties(v *schema.Set, subscriptionID, resGroup, appInsightsName string) *[]string { +func ExpandApplicationInsightsAPIKeyLinkedProperties(v *schema.Set, appInsightsId string) *[]string { if v == nil { return nil } - baseLinkedProperty := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/microsoft.insights/components/%s", subscriptionID, resGroup, appInsightsName) - result := make([]string, v.Len()) for i, prop := range v.List() { - result[i] = fmt.Sprintf("%s/%s", baseLinkedProperty, prop) + result[i] = fmt.Sprintf("%s/%s", appInsightsId, prop) } return &result } diff --git a/azurerm/resource_arm_application_insights_api_key.go b/azurerm/resource_arm_application_insights_api_key.go index ee42ce5b36b5..f451dc97a90e 100644 --- a/azurerm/resource_arm_application_insights_api_key.go +++ b/azurerm/resource_arm_application_insights_api_key.go @@ -36,14 +36,12 @@ func resourceArmApplicationInsightsAPIKey() *schema.Resource { Sensitive: true, }, - "application_insights_name": { + "application_insights_id": { Type: schema.TypeString, Required: true, ForceNew: true, }, - "resource_group_name": resourceGroupNameSchema(), - "read_permissions": { Type: schema.TypeSet, Optional: true, @@ -76,8 +74,15 @@ func resourceArmApplicationInsightsAPIKeyCreate(d *schema.ResourceData, meta int log.Printf("[INFO] preparing arguments for AzureRM Application Insights API key creation.") name := d.Get("name").(string) - resGroup := d.Get("resource_group_name").(string) - appInsightsName := d.Get("application_insights_name").(string) + appInsightsID := d.Get("application_insights_id").(string) + + id, err := parseAzureResourceID(appInsightsID) + if err != nil { + return err + } + + resGroup := id.ResourceGroup + appInsightsName := id.Path["components"] if requireResourcesToBeImported && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, appInsightsName, name) @@ -94,8 +99,8 @@ func resourceArmApplicationInsightsAPIKeyCreate(d *schema.ResourceData, meta int apiKeyProperties := insights.APIKeyRequest{ Name: &name, - LinkedReadProperties: azure.ExpandApplicationInsightsAPIKeyLinkedProperties(d.Get("read_permissions").(*schema.Set), client.SubscriptionID, resGroup, appInsightsName), - LinkedWriteProperties: azure.ExpandApplicationInsightsAPIKeyLinkedProperties(d.Get("write_permissions").(*schema.Set), client.SubscriptionID, resGroup, appInsightsName), + LinkedReadProperties: azure.ExpandApplicationInsightsAPIKeyLinkedProperties(d.Get("read_permissions").(*schema.Set), appInsightsID), + LinkedWriteProperties: azure.ExpandApplicationInsightsAPIKeyLinkedProperties(d.Get("write_permissions").(*schema.Set), appInsightsID), } result, err := client.Create(ctx, resGroup, appInsightsName, apiKeyProperties) @@ -143,8 +148,7 @@ func resourceArmApplicationInsightsAPIKeyRead(d *schema.ResourceData, meta inter return fmt.Errorf("Error making Read request on AzureRM Application Insights API key '%s': %+v", keyID, err) } - d.Set("resource_group_name", resGroup) - d.Set("application_insights_name", appInsightsName) + d.Set("application_insights_id", fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/microsoft.insights/components/%s", client.SubscriptionID, resGroup, appInsightsName)) d.Set("name", resp.Name) readProps := azure.FlattenApplicationInsightsAPIKeyLinkedProperties(resp.LinkedReadProperties) diff --git a/azurerm/resource_arm_application_insights_api_key_test.go b/azurerm/resource_arm_application_insights_api_key_test.go index e5fd8810bc07..96f01c82e463 100644 --- a/azurerm/resource_arm_application_insights_api_key_test.go +++ b/azurerm/resource_arm_application_insights_api_key_test.go @@ -191,10 +191,14 @@ func testCheckAzureRMApplicationInsightsAPIKeyDestroy(s *terraform.State) error } name := rs.Primary.Attributes["name"] - resourceGroup := rs.Primary.Attributes["resource_group_name"] - appInsightsName := rs.Primary.Attributes["application_insights_name"] + id, err := parseAzureResourceID(rs.Primary.Attributes["id"]) + if err != nil { + return err + } + resGroup := id.ResourceGroup + appInsightsName := id.Path["components"] - resp, err := conn.Get(ctx, resourceGroup, appInsightsName, name) + resp, err := conn.Get(ctx, resGroup, appInsightsName, name) if err != nil { return nil @@ -221,26 +225,19 @@ func testCheckAzureRMApplicationInsightsAPIKeyExists(name string) resource.TestC return err } keyID := id.Path["APIKeys"] - - resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] - if !hasResourceGroup { - return fmt.Errorf("Bad: no resource group found in state for App Insights API Key: %s", name) - } - appInsightsName, hasAppInsightsName := rs.Primary.Attributes["application_insights_name"] - if !hasAppInsightsName { - return fmt.Errorf("Bad: no Application Insights resource found in state for App Insights API Key: %s", name) - } + resGroup := id.ResourceGroup + appInsightsName := id.Path["components"] conn := testAccProvider.Meta().(*ArmClient).appInsightsAPIKeyClient ctx := testAccProvider.Meta().(*ArmClient).StopContext - resp, err := conn.Get(ctx, resourceGroup, appInsightsName, keyID) + resp, err := conn.Get(ctx, resGroup, appInsightsName, keyID) if err != nil { return fmt.Errorf("Bad: Get on appInsightsAPIKeyClient: %+v", err) } if resp.StatusCode == http.StatusNotFound { - return fmt.Errorf("Bad: Application Insights API Key '%q' (resource group: '%q') does not exist", name, resourceGroup) + return fmt.Errorf("Bad: Application Insights API Key '%q' (resource group: '%q') does not exist", name, resGroup) } return nil @@ -262,11 +259,10 @@ resource "azurerm_application_insights" "test" { } resource "azurerm_application_insights_api_key" "test" { - name = "acctestappinsightsapikey-%d" - application_insights_name = "${azurerm_application_insights.test.name}" - resource_group_name = "${azurerm_resource_group.test.name}" - read_permissions = %s - write_permissions = %s + name = "acctestappinsightsapikey-%d" + application_insights_id = "${azurerm_application_insights.test.id}" + read_permissions = %s + write_permissions = %s } `, rInt, location, rInt, rInt, readPerms, writePerms) } @@ -277,11 +273,10 @@ func testAccAzureRMApplicationInsightsAPIKey_requiresImport(rInt int, location, %s resource "azurerm_application_insights_api_key" "import" { - name = "${azurerm_application_insights_api_key.test.name}" - application_insights_name = "${azurerm_application_insights_api_key.test.application_insights_name}" - resource_group_name = "${azurerm_application_insights_api_key.test.resource_group_name}" - read_permissions = "${azurerm_application_insights_api_key.test.read_permissions}" - write_permissions = "${azurerm_application_insights_api_key.test.write_permissions}" + name = "${azurerm_application_insights_api_key.test.name}" + application_insights_id = "${azurerm_application_insights_api_key.test.application_insights_id}" + read_permissions = "${azurerm_application_insights_api_key.test.read_permissions}" + write_permissions = "${azurerm_application_insights_api_key.test.write_permissions}" } `, template) } From d6a613406a3bcc1eecea3b3292cd30c0d3325e85 Mon Sep 17 00:00:00 2001 From: Patrick Decat Date: Fri, 21 Dec 2018 12:38:22 +0100 Subject: [PATCH 05/17] Remove superfluous status code check --- azurerm/resource_arm_application_insights_api_key.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/azurerm/resource_arm_application_insights_api_key.go b/azurerm/resource_arm_application_insights_api_key.go index f451dc97a90e..6581239946a5 100644 --- a/azurerm/resource_arm_application_insights_api_key.go +++ b/azurerm/resource_arm_application_insights_api_key.go @@ -108,10 +108,6 @@ func resourceArmApplicationInsightsAPIKeyCreate(d *schema.ResourceData, meta int return fmt.Errorf("Error creating Application Insights API key %q (Resource Group %q): %+v", name, resGroup, err) } - if result.Response.StatusCode != http.StatusOK { - return fmt.Errorf("Error creating Application Insights API key %q (Resource Group %q): %+v", name, resGroup, result.Response) - } - if result.APIKey == nil { return fmt.Errorf("Error creating Application Insights API key %q (Resource Group %q): got empty API key", name, resGroup) } From 4b1c309f6f6dada9a89a19250da864ae660c8dc7 Mon Sep 17 00:00:00 2001 From: Patrick Decat Date: Fri, 21 Dec 2018 12:44:01 +0100 Subject: [PATCH 06/17] Use `utils.ResponseWasNotFound` helper to check API response status code --- .../resource_arm_application_insights_api_key.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/azurerm/resource_arm_application_insights_api_key.go b/azurerm/resource_arm_application_insights_api_key.go index 6581239946a5..3cb63d726340 100644 --- a/azurerm/resource_arm_application_insights_api_key.go +++ b/azurerm/resource_arm_application_insights_api_key.go @@ -3,7 +3,6 @@ package azurerm import ( "fmt" "log" - "net/http" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" @@ -135,9 +134,10 @@ func resourceArmApplicationInsightsAPIKeyRead(d *schema.ResourceData, meta inter appInsightsName := id.Path["components"] keyID := id.Path["apikeys"] - resp, err := client.Get(ctx, resGroup, appInsightsName, keyID) + result, err := client.Get(ctx, resGroup, appInsightsName, keyID) if err != nil { - if utils.ResponseWasNotFound(resp.Response) { + if utils.ResponseWasNotFound(result.Response) { + log.Printf("[WARN] AzureRM Application Insights API key '%s' not found, removing from state", id) d.SetId("") return nil } @@ -146,12 +146,12 @@ func resourceArmApplicationInsightsAPIKeyRead(d *schema.ResourceData, meta inter d.Set("application_insights_id", fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/microsoft.insights/components/%s", client.SubscriptionID, resGroup, appInsightsName)) - d.Set("name", resp.Name) - readProps := azure.FlattenApplicationInsightsAPIKeyLinkedProperties(resp.LinkedReadProperties) + d.Set("name", result.Name) + readProps := azure.FlattenApplicationInsightsAPIKeyLinkedProperties(result.LinkedReadProperties) if err := d.Set("read_permissions", readProps); err != nil { return fmt.Errorf("Error flattening `read_permissions `: %s", err) } - writeProps := azure.FlattenApplicationInsightsAPIKeyLinkedProperties(resp.LinkedWriteProperties) + writeProps := azure.FlattenApplicationInsightsAPIKeyLinkedProperties(result.LinkedWriteProperties) if err := d.Set("write_permissions", writeProps); err != nil { return fmt.Errorf("Error flattening `write_permissions `: %s", err) } @@ -173,9 +173,9 @@ func resourceArmApplicationInsightsAPIKeyDelete(d *schema.ResourceData, meta int log.Printf("[DEBUG] Deleting AzureRM Application Insights API key '%s' (resource group '%s')", keyID, resGroup) - resp, err := client.Delete(ctx, resGroup, appInsightsName, keyID) + result, err := client.Delete(ctx, resGroup, appInsightsName, keyID) if err != nil { - if resp.StatusCode == http.StatusNotFound { + if utils.ResponseWasNotFound(result.Response) { return nil } return fmt.Errorf("Error issuing AzureRM delete request for Application Insights API key '%s': %+v", keyID, err) From 9e7320867d8b922be5eba7f53a98583b1f0ddb16 Mon Sep 17 00:00:00 2001 From: Tom Harvey Date: Fri, 21 Dec 2018 12:46:39 +0100 Subject: [PATCH 07/17] Enforce read & write permissions values Co-Authored-By: pdecat --- azurerm/helpers/validate/strings.go | 14 -------------- .../resource_arm_application_insights_api_key.go | 6 +++--- 2 files changed, 3 insertions(+), 17 deletions(-) diff --git a/azurerm/helpers/validate/strings.go b/azurerm/helpers/validate/strings.go index 2c8b6bd2c7b8..1dec1bd2e07f 100644 --- a/azurerm/helpers/validate/strings.go +++ b/azurerm/helpers/validate/strings.go @@ -18,17 +18,3 @@ func NoEmptyStrings(i interface{}, k string) ([]string, []error) { return nil, nil } - -// LowercaseString validates that the string is all lower case characters -func LowercaseString(i interface{}, k string) ([]string, []error) { - v, ok := i.(string) - if !ok { - return nil, []error{fmt.Errorf("expected type of %q to be string", k)} - } - - if v != strings.ToLower(v) { - return nil, []error{fmt.Errorf("%q must not be lower case", k)} - } - - return nil, nil -} diff --git a/azurerm/resource_arm_application_insights_api_key.go b/azurerm/resource_arm_application_insights_api_key.go index 3cb63d726340..d262728da8ce 100644 --- a/azurerm/resource_arm_application_insights_api_key.go +++ b/azurerm/resource_arm_application_insights_api_key.go @@ -6,10 +6,10 @@ import ( "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/helpers/validate" "github.com/Azure/azure-sdk-for-go/services/appinsights/mgmt/2015-05-01/insights" "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -48,7 +48,7 @@ func resourceArmApplicationInsightsAPIKey() *schema.Resource { Set: schema.HashString, Elem: &schema.Schema{ Type: schema.TypeString, - ValidateFunc: validate.LowercaseString, + ValidateFunc: validation.StringInSlice([]string{"agentconfig", "aggregate", "api", "draft", "extendqueries", "search"}, false), }, }, @@ -59,7 +59,7 @@ func resourceArmApplicationInsightsAPIKey() *schema.Resource { Set: schema.HashString, Elem: &schema.Schema{ Type: schema.TypeString, - ValidateFunc: validate.LowercaseString, + ValidateFunc: validation.StringInSlice([]string{"annotations"}, false), }, }, }, From f5d343eba4f7e6553f24baafaf2c407bf6402d55 Mon Sep 17 00:00:00 2001 From: Patrick Decat Date: Fri, 21 Dec 2018 14:50:56 +0100 Subject: [PATCH 08/17] Fix err declaration shadowing reported by vetshadow linter --- azurerm/resource_arm_application_insights_api_key.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/azurerm/resource_arm_application_insights_api_key.go b/azurerm/resource_arm_application_insights_api_key.go index d262728da8ce..2fd24f05139e 100644 --- a/azurerm/resource_arm_application_insights_api_key.go +++ b/azurerm/resource_arm_application_insights_api_key.go @@ -84,7 +84,8 @@ func resourceArmApplicationInsightsAPIKeyCreate(d *schema.ResourceData, meta int appInsightsName := id.Path["components"] if requireResourcesToBeImported && d.IsNewResource() { - existing, err := client.Get(ctx, resGroup, appInsightsName, name) + var existing insights.ApplicationInsightsComponentAPIKey + existing, err = client.Get(ctx, resGroup, appInsightsName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { return fmt.Errorf("Error checking for presence of existing Application Insights API key %q (Resource Group %q): %s", name, resGroup, err) From f017364e314903e03e71b0294bb2b92190ff41a2 Mon Sep 17 00:00:00 2001 From: Patrick Decat Date: Fri, 21 Dec 2018 17:37:40 +0100 Subject: [PATCH 09/17] Add documentation --- website/azurerm.erb | 4 + ...application_insights_api_key.html.markdown | 101 ++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 website/docs/r/application_insights_api_key.html.markdown diff --git a/website/azurerm.erb b/website/azurerm.erb index b4f6586222bd..959c2ed446d9 100644 --- a/website/azurerm.erb +++ b/website/azurerm.erb @@ -371,6 +371,10 @@ > azurerm_application_insights + + > + azurerm_application_insights_api_key + diff --git a/website/docs/r/application_insights_api_key.html.markdown b/website/docs/r/application_insights_api_key.html.markdown new file mode 100644 index 000000000000..ffd3b982091e --- /dev/null +++ b/website/docs/r/application_insights_api_key.html.markdown @@ -0,0 +1,101 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_application_insights_api_key" +sidebar_current: "docs-azurerm-resource-application-insights-api-key" +description: |- + Manages an Application Insights API key. +--- + +# azurerm_application_insights_api_key + +Manages an Application Insights API key. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "test" { + name = "tf-test" + location = "West Europe" +} + +resource "azurerm_application_insights" "test" { + name = "tf-test-appinsights" + location = "West Europe" + resource_group_name = "${azurerm_resource_group.test.name}" + application_type = "Web" +} + +resource "azurerm_application_insights_api_key" "read_telemetry" { + name = "tf-test-appinsights-api-key" + application_insights_id = "${azurerm_application_insights.test.id}" + read_permissions = ["aggregate", "api", "draft", "extendqueries", "search"] +} + +resource "azurerm_application_insights_api_key" "write_annotations" { + name = "tf-test-appinsights-api-key" + application_insights_id = "${azurerm_application_insights.test.id}" + write_permissions = ["annotations"] +} + +resource "azurerm_application_insights_api_key" "authenticate_sdk_control_channel" { + name = "tf-test-appinsights-api-key" + application_insights_id = "${azurerm_application_insights.test.id}" + read_permissions = ["agentconfig"] +} + +resource "azurerm_application_insights_api_key" "full_permissions" { + name = "tf-test-appinsights-api-key" + application_insights_id = "${azurerm_application_insights.test.id}" + read_permissions = ["agentconfig", "aggregate", "api", "draft", "extendqueries", "search"] + write_permissions = ["annotations"] +} + +output "read_telemetry_api_key" { + value = "${azurerm_application_insights.read_telemetry.api_key}" +} + +output "write_annotations_api_key" { + value = "${azurerm_application_insights.write_annotations.app_id}" +} + +output "authenticate_sdk_control_channel" { + value = "${azurerm_application_insights.authenticate_sdk_control_channel.app_id}" +} + +output "full_permissions_api_key" { + value = "${azurerm_application_insights.full_permissions.app_id}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the Application Insights API key. Changing this forces a + new resource to be created. + +* `application_insights_id` - (Required) The ID of the Application Insights component on which the API key operates. Changing this forces a new resource to be created. + +* `read_permissions` - (Optional) Specifies the list of read permissions granted to the API key. Valid values are `agentconfig`, `aggregate`, `api`, `draft`, `extendqueries`, `search`. Please note these values are case sensitive. Changing this forces a new resource to be created. + +* `write_permissions` - (Optional) Specifies the list of write permissions granted to the API key. Valid values are `annotations`. Please note these values are case sensitive. Changing this forces a new resource to be created. + +-> **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 API key. + +* `api_key` - The API Key secret (Sensitive). + +## Import + +Application Insights API keys can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_application_insights_api_key.my_key/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/microsoft.insights/components/instance1/apikeys/00000000-0000-0000-0000-000000000000 +``` + +-> **Note:** The secret `api_key` cannot be retrieved after creation. You will need to edit the state by hand to set the secret value if you happen to have it backed up somewhere. \ No newline at end of file From a24e687003f1ce09878b44be3b17ea8f7eba5af6 Mon Sep 17 00:00:00 2001 From: Patrick Decat Date: Fri, 21 Dec 2018 17:42:07 +0100 Subject: [PATCH 10/17] Fix api keys names in documentation example --- website/docs/r/application_insights_api_key.html.markdown | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/website/docs/r/application_insights_api_key.html.markdown b/website/docs/r/application_insights_api_key.html.markdown index ffd3b982091e..e15f95591282 100644 --- a/website/docs/r/application_insights_api_key.html.markdown +++ b/website/docs/r/application_insights_api_key.html.markdown @@ -26,25 +26,25 @@ resource "azurerm_application_insights" "test" { } resource "azurerm_application_insights_api_key" "read_telemetry" { - name = "tf-test-appinsights-api-key" + name = "tf-test-appinsights-read-telemetry-api-key" application_insights_id = "${azurerm_application_insights.test.id}" read_permissions = ["aggregate", "api", "draft", "extendqueries", "search"] } resource "azurerm_application_insights_api_key" "write_annotations" { - name = "tf-test-appinsights-api-key" + name = "tf-test-appinsights-write-annotations-api-key" application_insights_id = "${azurerm_application_insights.test.id}" write_permissions = ["annotations"] } resource "azurerm_application_insights_api_key" "authenticate_sdk_control_channel" { - name = "tf-test-appinsights-api-key" + name = "tf-test-appinsights-authenticate-sdk-control-channel-api-key" application_insights_id = "${azurerm_application_insights.test.id}" read_permissions = ["agentconfig"] } resource "azurerm_application_insights_api_key" "full_permissions" { - name = "tf-test-appinsights-api-key" + name = "tf-test-appinsights-full-permissions-api-key" application_insights_id = "${azurerm_application_insights.test.id}" read_permissions = ["agentconfig", "aggregate", "api", "draft", "extendqueries", "search"] write_permissions = ["annotations"] From 4e3b1a1191147f136aa6e0e860098ec7abfcdd08 Mon Sep 17 00:00:00 2001 From: Patrick Decat Date: Fri, 21 Dec 2018 17:42:54 +0100 Subject: [PATCH 11/17] Fix api keys outputs in documentation example --- website/docs/r/application_insights_api_key.html.markdown | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/website/docs/r/application_insights_api_key.html.markdown b/website/docs/r/application_insights_api_key.html.markdown index e15f95591282..d1665d8e3cf9 100644 --- a/website/docs/r/application_insights_api_key.html.markdown +++ b/website/docs/r/application_insights_api_key.html.markdown @@ -51,19 +51,19 @@ resource "azurerm_application_insights_api_key" "full_permissions" { } output "read_telemetry_api_key" { - value = "${azurerm_application_insights.read_telemetry.api_key}" + value = "${azurerm_application_insights_api_key.read_telemetry.api_key}" } output "write_annotations_api_key" { - value = "${azurerm_application_insights.write_annotations.app_id}" + value = "${azurerm_application_insights_api_key.write_annotations.app_id}" } output "authenticate_sdk_control_channel" { - value = "${azurerm_application_insights.authenticate_sdk_control_channel.app_id}" + value = "${azurerm_application_insights_api_key.authenticate_sdk_control_channel.app_id}" } output "full_permissions_api_key" { - value = "${azurerm_application_insights.full_permissions.app_id}" + value = "${azurerm_application_insights_api_key.full_permissions.app_id}" } ``` From 7a5dee466c3342fc068c702c6d9ee418cabb4051 Mon Sep 17 00:00:00 2001 From: Patrick Decat Date: Fri, 21 Dec 2018 17:45:35 +0100 Subject: [PATCH 12/17] Fix api keys outputs in documentation example --- website/docs/r/application_insights_api_key.html.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/website/docs/r/application_insights_api_key.html.markdown b/website/docs/r/application_insights_api_key.html.markdown index d1665d8e3cf9..18cf843c76f2 100644 --- a/website/docs/r/application_insights_api_key.html.markdown +++ b/website/docs/r/application_insights_api_key.html.markdown @@ -55,15 +55,15 @@ output "read_telemetry_api_key" { } output "write_annotations_api_key" { - value = "${azurerm_application_insights_api_key.write_annotations.app_id}" + value = "${azurerm_application_insights_api_key.write_annotations.api_key}" } output "authenticate_sdk_control_channel" { - value = "${azurerm_application_insights_api_key.authenticate_sdk_control_channel.app_id}" + value = "${azurerm_application_insights_api_key.authenticate_sdk_control_channel.api_key}" } output "full_permissions_api_key" { - value = "${azurerm_application_insights_api_key.full_permissions.app_id}" + value = "${azurerm_application_insights_api_key.full_permissions.api_key}" } ``` From 3ad15594f565ef25324669d1ca12e13b44ded983 Mon Sep 17 00:00:00 2001 From: kt Date: Mon, 24 Dec 2018 23:35:44 +0100 Subject: [PATCH 13/17] Update website/docs/r/application_insights_api_key.html.markdown Co-Authored-By: pdecat --- website/docs/r/application_insights_api_key.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/application_insights_api_key.html.markdown b/website/docs/r/application_insights_api_key.html.markdown index 18cf843c76f2..3550e5634449 100644 --- a/website/docs/r/application_insights_api_key.html.markdown +++ b/website/docs/r/application_insights_api_key.html.markdown @@ -98,4 +98,4 @@ Application Insights API keys can be imported using the `resource id`, e.g. terraform import azurerm_application_insights_api_key.my_key/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/microsoft.insights/components/instance1/apikeys/00000000-0000-0000-0000-000000000000 ``` --> **Note:** The secret `api_key` cannot be retrieved after creation. You will need to edit the state by hand to set the secret value if you happen to have it backed up somewhere. \ No newline at end of file +-> **Note:** The secret `api_key` cannot be retrieved during an import. You will need to edit the state by hand to set the secret value if you happen to have it backed up somewhere. From ec8ad787df0423e268762af213ad16810763d372 Mon Sep 17 00:00:00 2001 From: Patrick Decat Date: Thu, 27 Dec 2018 13:44:58 +0100 Subject: [PATCH 14/17] Let expander & flattener functions return empty array instead of nil --- azurerm/helpers/azure/app_insights.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/azurerm/helpers/azure/app_insights.go b/azurerm/helpers/azure/app_insights.go index 3cc7833d77cc..21fb6944844a 100644 --- a/azurerm/helpers/azure/app_insights.go +++ b/azurerm/helpers/azure/app_insights.go @@ -9,7 +9,7 @@ import ( func ExpandApplicationInsightsAPIKeyLinkedProperties(v *schema.Set, appInsightsId string) *[]string { if v == nil { - return nil + return &[]string{} } result := make([]string, v.Len()) @@ -21,7 +21,7 @@ func ExpandApplicationInsightsAPIKeyLinkedProperties(v *schema.Set, appInsightsI func FlattenApplicationInsightsAPIKeyLinkedProperties(props *[]string) *[]string { if props == nil { - return nil + return &[]string{} } result := make([]string, len(*props)) From d42ad5b9306a93f33cbf12a75d5e5d7453b3719d Mon Sep 17 00:00:00 2001 From: Patrick Decat Date: Thu, 27 Dec 2018 13:53:07 +0100 Subject: [PATCH 15/17] Add minimal validation to azurerm_application_insights_api_key's name field --- azurerm/resource_arm_application_insights_api_key.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/azurerm/resource_arm_application_insights_api_key.go b/azurerm/resource_arm_application_insights_api_key.go index 2fd24f05139e..041d6c23d204 100644 --- a/azurerm/resource_arm_application_insights_api_key.go +++ b/azurerm/resource_arm_application_insights_api_key.go @@ -24,9 +24,10 @@ func resourceArmApplicationInsightsAPIKey() *schema.Resource { Schema: map[string]*schema.Schema{ "name": { - Type: schema.TypeString, - Required: true, - ForceNew: true, + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.NoZeroValues, }, "api_key": { From 1b0a4d845adea18e4f6e87716f8f036d9a7af4a6 Mon Sep 17 00:00:00 2001 From: Patrick Decat Date: Thu, 27 Dec 2018 13:54:18 +0100 Subject: [PATCH 16/17] Move api_key computed value at the bottom of schema --- azurerm/resource_arm_application_insights_api_key.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/azurerm/resource_arm_application_insights_api_key.go b/azurerm/resource_arm_application_insights_api_key.go index 041d6c23d204..882e0f205fdd 100644 --- a/azurerm/resource_arm_application_insights_api_key.go +++ b/azurerm/resource_arm_application_insights_api_key.go @@ -30,12 +30,6 @@ func resourceArmApplicationInsightsAPIKey() *schema.Resource { ValidateFunc: validation.NoZeroValues, }, - "api_key": { - Type: schema.TypeString, - Computed: true, - Sensitive: true, - }, - "application_insights_id": { Type: schema.TypeString, Required: true, @@ -63,6 +57,12 @@ func resourceArmApplicationInsightsAPIKey() *schema.Resource { ValidateFunc: validation.StringInSlice([]string{"annotations"}, false), }, }, + + "api_key": { + Type: schema.TypeString, + Computed: true, + Sensitive: true, + }, }, } } From b46ed17d825aadbe72ed928a1f591f0c58a1d130 Mon Sep 17 00:00:00 2001 From: Patrick Decat Date: Thu, 27 Dec 2018 13:55:27 +0100 Subject: [PATCH 17/17] Add validation to azurerm_application_insights_api_key's application_insights_id field --- azurerm/resource_arm_application_insights_api_key.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/azurerm/resource_arm_application_insights_api_key.go b/azurerm/resource_arm_application_insights_api_key.go index 882e0f205fdd..97257d315d37 100644 --- a/azurerm/resource_arm_application_insights_api_key.go +++ b/azurerm/resource_arm_application_insights_api_key.go @@ -31,9 +31,10 @@ func resourceArmApplicationInsightsAPIKey() *schema.Resource { }, "application_insights_id": { - Type: schema.TypeString, - Required: true, - ForceNew: true, + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateResourceID, }, "read_permissions": {