Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creating azure app insights resource #3

Merged
9 changes: 9 additions & 0 deletions azurerm/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"net/http"
"net/http/httputil"

"github.com/Azure/azure-sdk-for-go/arm/appinsights"
"github.com/Azure/azure-sdk-for-go/arm/cdn"
"github.com/Azure/azure-sdk-for-go/arm/compute"
"github.com/Azure/azure-sdk-for-go/arm/containerregistry"
Expand Down Expand Up @@ -104,6 +105,8 @@ type ArmClient struct {
keyVaultClient keyvault.VaultsClient

sqlElasticPoolsClient sql.ElasticPoolsClient

appInsightsClient appinsights.ComponentsClient
}

func withRequestLogging() autorest.SendDecorator {
Expand Down Expand Up @@ -476,6 +479,12 @@ func (c *Config) getArmClient() (*ArmClient, error) {
sqlepc.Sender = autorest.CreateSender(withRequestLogging())
client.sqlElasticPoolsClient = sqlepc

ai := appinsights.NewComponentsClientWithBaseURI(endpoint, c.SubscriptionID)
setUserAgent(&ai.Client)
ai.Authorizer = auth
ai.Sender = autorest.CreateSender(withRequestLogging())
client.appInsightsClient = ai

return &client, nil
}

Expand Down
34 changes: 34 additions & 0 deletions azurerm/import_arm_app_insights_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package azurerm

import (
"testing"

"fmt"

"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)

func TestAccAzureRMAppInsights_importBasic(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we rename these to ApplicationInsights for consistency?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(done)

resourceName := "azurerm_application_insights.test"

ri := acctest.RandInt()
config := fmt.Sprintf(testAccAzureRMApplicationInsights_basic, ri, ri)

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMAppInsightsDestroy,
Steps: []resource.TestStep{
{
Config: config,
},

{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}
2 changes: 2 additions & 0 deletions azurerm/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ func Provider() terraform.ResourceProvider {
"azurerm_virtual_network": resourceArmVirtualNetwork(),
"azurerm_virtual_network_peering": resourceArmVirtualNetworkPeering(),

"azurerm_application_insights": resourceArmApplicationInsights(),

// These resources use the Riviera SDK
"azurerm_dns_a_record": resourceArmDnsARecord(),
"azurerm_dns_aaaa_record": resourceArmDnsAAAARecord(),
Expand Down
150 changes: 150 additions & 0 deletions azurerm/resource_arm_app_insights.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
package azurerm

import (
"fmt"
"log"
"net/http"

"github.com/Azure/azure-sdk-for-go/arm/appinsights"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"
)

func resourceArmApplicationInsights() *schema.Resource {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we add some documentation for this resource too?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(done)

return &schema.Resource{
Create: resourceArmApplicationInsightsCreateOrUpdate,
Read: resourceArmApplicationInsightsRead,
Update: resourceArmApplicationInsightsCreateOrUpdate,
Delete: resourceArmApplicationInsightsDelete,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there's tests for import, but this resource doesn't currently support it - could we add the code to do this?

Importer: &schema.ResourceImporter{
    State: schema.ImportStatePassthrough,
},


Schema: map[string]*schema.Schema{
"resource_group_name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"application_type": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
DiffSuppressFunc: ignoreCaseDiffSuppressFunc,
ValidateFunc: validation.StringInSlice([]string{
string(appinsights.Web),
string(appinsights.Other),
}, true),
},
"location": locationSchema(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there's some other fields we should provide here:

"application_id": {
  Type:     schema.TypeString,
  Required: true,
  ForceNew: true,
},

"application_type": {
  Type:             schema.TypeString,
  Required:         true,
  ForceNew:         true,
  DiffSuppressFunc: ignoreCaseDiffSuppressFunc,
  ValidateFunc: validation.StringInSlice([]string{
    appinsights.Web,
    appinsights.Other,
  ), true),
},

"tags": tagsSchema(),
"instrumentation_key": {
Type: schema.TypeString,
Computed: true,
},
},
}
}

func resourceArmApplicationInsightsCreateOrUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*ArmClient)
AppInsightsClient := client.appInsightsClient

log.Printf("[INFO] preparing arguments for AzureRM Application Insights creation.")

name := d.Get("name").(string)
resGroup := d.Get("resource_group_name").(string)
applicationType := d.Get("application_type").(string)
location := d.Get("location").(string)
tags := d.Get("tags").(map[string]interface{})

applicationInsightsComponentProperties := appinsights.ApplicationInsightsComponentProperties{
ApplicationID: &name,
ApplicationType: appinsights.ApplicationType(applicationType),
}

insightProperties := appinsights.ApplicationInsightsComponent{
Name: &name,
Location: &location,
Tags: expandTags(tags),
Kind: &applicationType,
ApplicationInsightsComponentProperties: &applicationInsightsComponentProperties,
}

_, err := AppInsightsClient.CreateOrUpdate(resGroup, name, insightProperties)
if err != nil {
return err
}

read, err := AppInsightsClient.Get(resGroup, name)
if err != nil {
return err
}
if read.ID == nil {
return fmt.Errorf("Cannot read application insights %s (resource group %s) ID", name, resGroup)
}

d.SetId(*read.ID)

return resourceArmApplicationInsightsRead(d, meta)
}

func resourceArmApplicationInsightsRead(d *schema.ResourceData, meta interface{}) error {
AppInsightsClient := meta.(*ArmClient).appInsightsClient

id, err := parseAzureResourceID(d.Id())
if err != nil {
return err
}

log.Printf("[DEBUG] Reading application insights %s", id)

resGroup := id.ResourceGroup
name := id.Path["components"]

resp, err := AppInsightsClient.Get(resGroup, name)
if err != nil {
if resp.StatusCode == http.StatusNotFound {
d.SetId("")
return nil
}
return fmt.Errorf("Error making Read request on AzureRM application insights %s: %s", name, err)
}

d.Set("name", name)
d.Set("resource_group_name", resGroup)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we also set the location field here:

d.Set("location", azureRMNormalizeLocation(*resp.Location))

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(done)

if resp.ApplicationInsightsComponentProperties != nil {
d.Set("application_id", resp.ApplicationInsightsComponentProperties.ApplicationID)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From what I can see, ApplicationID appears to be the same as the name in all circumstances - as such I think we should be exposing AppID instead?

d.Set("application_type", string(resp.ApplicationInsightsComponentProperties.ApplicationType))
d.Set("instrumentation_key", resp.ApplicationInsightsComponentProperties.InstrumentationKey)
}

flattenAndSetTags(d, resp.Tags)

return nil
}

func resourceArmApplicationInsightsDelete(d *schema.ResourceData, meta interface{}) error {
AppInsightsClient := meta.(*ArmClient).appInsightsClient

id, err := parseAzureResourceID(d.Id())
if err != nil {
return err
}
resGroup := id.ResourceGroup
name := id.Path["components"]

log.Printf("[DEBUG] Deleting application insights %s: %s", resGroup, name)

resp, err := AppInsightsClient.Delete(resGroup, name)
if err != nil {
if resp.StatusCode == http.StatusNotFound {
return nil
}
return fmt.Errorf("Error issuing AzureRM delete request for Application Insights '%s': %+v", name, err)
}

return err
}
98 changes: 98 additions & 0 deletions azurerm/resource_arm_app_insights_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package azurerm

import (
"fmt"
"net/http"
"testing"

"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)

func TestAccAzureRMAppInsights_basic(t *testing.T) {

ri := acctest.RandInt()
config := fmt.Sprintf(testAccAzureRMApplicationInsights_basic, ri, ri)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for newer resources we're tending to make these functions return a formatted strings, i.e. func testAccAzureRMApplicationInsights_basic(ri)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(done)


resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMAppInsightsDestroy,
Steps: []resource.TestStep{
{
Config: config,
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMAppInsightsExists("azurerm_application_insights.test"),
),
},
},
})
}

func testCheckAzureRMAppInsightsDestroy(s *terraform.State) error {
conn := testAccProvider.Meta().(*ArmClient).appInsightsClient

for _, rs := range s.RootModule().Resources {
if rs.Type != "azurerm_application_insights" {
continue
}

name := rs.Primary.Attributes["name"]
resourceGroup := rs.Primary.Attributes["resource_group_name"]

resp, err := conn.Get(resourceGroup, name)

if err != nil {
return nil
}

if resp.StatusCode != http.StatusNotFound {
return fmt.Errorf("App Insights still exists:\n%#v", resp.ApplicationInsightsComponentProperties)
}
}

return nil
}

func testCheckAzureRMAppInsightsExists(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)
}

name := rs.Primary.Attributes["name"]
resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"]
if !hasResourceGroup {
return fmt.Errorf("Bad: no resource group found in state for App Insights: %s", name)
}

conn := testAccProvider.Meta().(*ArmClient).appInsightsClient

resp, err := conn.Get(resourceGroup, name)
if err != nil {
return fmt.Errorf("Bad: Get on appInsightsClient: %s", err)
}

if resp.StatusCode == http.StatusNotFound {
return fmt.Errorf("Bad: App Insights %q (resource group: %q) does not exist", name, resourceGroup)
}

return nil
}
}

var testAccAzureRMApplicationInsights_basic = `
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it'd be good to include a test for the other application_type here too if possible

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(done)

resource "azurerm_resource_group" "test" {
name = "acctestRG-%d"
location = "West Europe"
}
resource "azurerm_application_insights" "test" {
name = "acctestappinsights-%d"
location = "West Europe"
resource_group_name = "${azurerm_resource_group.test.name}"
application_type = "web"
}
`

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading