Azure / azure-libraries-for-net

Azure libraries for .Net
MIT License
380 stars 192 forks source link

How to provision Application Insights #210

Closed wis3guy closed 6 years ago

wis3guy commented 6 years ago

I know

My question is, how do i create an Application Insights resource using the generic resources route? I struggle to map this:

{
  "name": "string",
  "type": "microsoft.insights/components",
  "apiVersion": "2015-05-01",
  "location": "string",
  "tags": {},
  "kind": "string",
  "properties": {
    "Application_Type": "string",
    "Flow_Type": "Bluefield",
    "Request_Source": "rest",
    "HockeyAppId": "string",
    "SamplingPercentage": integer
  }
}

Taken from: https://docs.microsoft.com/en-us/azure/templates/microsoft.insights/components

to something like this:

var insights = ResourceManager
    .Configure()
    .Authenticate(credentials).WithSubscription(azure.SubscriptionId)
    .GenericResources.Define($"{pfx}-ai")
    .WithRegion(region)
    .WithExistingResourceGroup(rg)
    .WithResourceType("microsoft.insights/components")
    .WithProviderNamespace("tbd") // TODO
    .WithPlan("tbd") // TODO
    .WithApiVersion("tbd") // TODO
    .WithProperties(new {}) // TODO
    .Create();

My goal is to provision this resource and set the APPINSIGHTS_INSTRUMENTATIONKEY on all of the subsequently created App Services and Function Apps.

Some guidance would be much appreciated.

wis3guy commented 6 years ago

I figured it out myself. Leaving this comment for future reference.

var insights = ResourceManager
    .Configure()
    .Authenticate(credentials).WithSubscription(azure.SubscriptionId)
    .GenericResources.Define($"{options.Prefix}-ai")
    .WithRegion(options.Region)
    .WithExistingResourceGroup(rg)
    .WithResourceType("components")
    .WithProviderNamespace("microsoft.insights")
    .WithoutPlan()
    .WithApiVersion("2015-05-01")
    .WithParentResource("")
    .WithProperties(new
    {
        Application_Type = "web"
    })
    .Create();

var token = ((JObject) insights.Properties)["InstrumentationKey"];

var instrumentationKey = token?.Value<string>() ?? string.Empty;
luthus commented 6 years ago

It doesn't look like the properties are passed to the API if an anonymous object is used. It's not immediately obvious unless you set the type to "other" though.

The following works though:

var insights = ResourceManager
                    .Configure()
                    .Authenticate(credentials).WithSubscription(azure.SubscriptionId)
                    .GenericResources.Define($"{options.Prefix}-ai")
                    .WithRegion(options.Region)
                    .WithExistingResourceGroup(rg)
                    .WithResourceType("components")
                    .WithProviderNamespace("microsoft.insights")
                    .WithoutPlan()
                    .WithApiVersion("2015-05-01")
                    .WithParentResource("")
                    .WithProperties(new Dictionary<string, string>()
                    {
                        { "Application_Type", "other"}
                    })
                    .Create();

Using a strongly typed object works too.

public class ApplicationInsightsProperties
{
    public string Application_Type { get; set; }
}
var insights = ResourceManager
                   .Configure()
                   .Authenticate(credentials).WithSubscription(azure.SubscriptionId)
                   .GenericResources.Define($"{options.Prefix}-ai")
                   .WithRegion(options.Region)
                   .WithExistingResourceGroup(rg)
                   .WithResourceType("components")
                   .WithProviderNamespace("microsoft.insights")
                   .WithoutPlan()
                   .WithApiVersion("2015-05-01")
                   .WithParentResource("")
                   .WithProperties(new ApplicationInsightsProperties
                   {
                       Application_Type = "other"
                   })
                   .Create();
wis3guy commented 6 years ago

@luthus Wow that is a great catch. I (clearly) only tested with my desired outcome ... which happened to be the default behavior.