Repository: serverless/serverless-azure-functions
Pull request #494 (2020-08-28 16:38:12)

feat: Allow custom app insights instrumentation key
<!--
1. Please check out and follow our Contributing Guidelines: https://github.com/serverless/serverless-azure-functions/CONTRIBUTING.md
2. Do not remove any section of the template. If something is not applicable leave it empty but leave it in the PR
3. Please follow the template, otherwise we'll have to ask you to update it and it will take longer until your PR is merged
-->

## What did you implement:

Enable custom app insights instrumentation key 

```yaml
provider:
  appInsights:
    instrumentationKey: {your_key}
```

<!--
Briefly describe the feature if no issue exists for this PR
-->

## How did you implement it:

If an instrumentation key is added, arm template will use that value instead of the key from the generated template

**Out of scope**: The default template will still create an instance of app insights - should be future PR to remove that

## How can we verify it:

Deploy a function app with a custom app insights instrumentation key

<!--
Add any applicable config, commands, screenshots or other resources
to make it easy for us to verify this works. The easier you make it for us
to review a PR, the faster we can review and merge it.

Examples:
* serverless.yml - Fully functioning to easily deploy changes
* Screenshots - Showing the difference between your output and the master
* Cloud Configuration - List cloud resources and show that the correct configuration is in place
* Other - Anything else that comes to mind to help us evaluate
-->

## Todos:

_**Note: Run `npm run test:ci` to run all validation checks on proposed changes**_

- [x] Ensure there are no lint errors.  
       **Validate via `npm run lint`**  
       _Note: Some reported issues can be automatically fixed by running `npm run lint:fix`_
- [x] Write tests and confirm existing functionality is not broken.  
       **Validate via `npm test`**
- [x] Write documentation
- [x] Provide verification config / commands / resources
- [x] Enable "Allow edits from maintainers" for this PR
- [x] Update the messages below

**_Is this ready for review?:_** YES  
**_Is it a breaking change?:_** NO



Patch:
diff --git a/src/armTemplates/resources/functionApp.ts b/src/armTemplates/resources/functionApp.ts
index bc5b561..890d4cb 100644
--- a/src/armTemplates/resources/functionApp.ts
+++ b/src/armTemplates/resources/functionApp.ts
@@ -1,4 +1,4 @@
-import { dockerImages, getRuntimeLanguage, getRuntimeVersion, FunctionAppOS, isNodeRuntime, Runtime, RuntimeLanguage, getFunctionWorkerRuntime } from "../../config/runtime";
+import { dockerImages, FunctionAppOS, getFunctionWorkerRuntime, getRuntimeVersion, isNodeRuntime } from "../../config/runtime";
 import { ArmParameter, ArmParameters, ArmParamType, ArmResourceTemplate, ArmResourceTemplateGenerator, DefaultArmParams } from "../../models/armTemplates";
 import { FunctionAppConfig, ServerlessAzureConfig } from "../../models/serverless";
 import { AzureNamingService, AzureNamingServiceOptions } from "../../services/namingService";
@@ -206,6 +206,9 @@ export class FunctionAppResource implements ArmResourceTemplateGenerator {
   }
 
   private getFunctionAppSettings(config: ServerlessAzureConfig): FunctionAppSetting[] {
+    const { appInsights } = config.provider;
+    const instrumentationKey = appInsights ? appInsights.instrumentationKey : undefined;
+
     let appSettings: FunctionAppSetting[] = [
       {
         name: "FUNCTIONS_WORKER_RUNTIME",
@@ -221,7 +224,7 @@ export class FunctionAppResource implements ArmResourceTemplateGenerator {
       },
       {
         name: "APPINSIGHTS_INSTRUMENTATIONKEY",
-        value: "[reference(concat('microsoft.insights/components/', parameters('appInsightsName'))).InstrumentationKey]"
+        value: instrumentationKey || "[reference(concat('microsoft.insights/components/', parameters('appInsightsName'))).InstrumentationKey]"
       }
     ];
 
diff --git a/src/models/serverless.ts b/src/models/serverless.ts
index dda033f..3a42741 100644
--- a/src/models/serverless.ts
+++ b/src/models/serverless.ts
@@ -23,6 +23,10 @@ export interface FunctionAppConfig extends ResourceConfig {
   extensionVersion?;
 }
 
+export interface AppInsightsConfig extends ResourceConfig {
+  instrumentationKey?: string;
+}
+
 export interface DeploymentConfig {
   rollback?: boolean;
   container?: string;
@@ -49,7 +53,7 @@ export interface ServerlessAzureProvider {
   resourceGroup?: string;
   apim?: ApiManagementConfig;
   functionApp?: FunctionAppConfig;
-  appInsights?: ResourceConfig;
+  appInsights?: AppInsightsConfig;
   appServicePlan?: AppServicePlanConfig;
   storageAccount?: ResourceConfig;
   hostingEnvironment?: ResourceConfig;
diff --git a/src/plugins/package/azurePackagePlugin.ts b/src/plugins/package/azurePackagePlugin.ts
index 73ad7cc..1890e26 100644
--- a/src/plugins/package/azurePackagePlugin.ts
+++ b/src/plugins/package/azurePackagePlugin.ts
@@ -1,12 +1,12 @@
 
 import Serverless from "serverless";
+import { BuildMode } from "../../config/runtime";
 import { ServerlessCliCommand } from "../../models/serverless";
 import AzureProvider from "../../provider/azureProvider";
+import { CompilerService } from "../../services/compilerService";
+import { ConfigService } from "../../services/configService";
 import { PackageService } from "../../services/packageService";
 import { AzureBasePlugin } from "../azureBasePlugin";
-import { isCompiledRuntime, BuildMode, FunctionAppOS } from "../../config/runtime";
-import { CompilerService } from "../../services/compilerService"
-import { ConfigService } from "../../services/configService";
 
 export class AzurePackagePlugin extends AzureBasePlugin {
   private bindingsCreated: boolean = false;


Test patch:
diff --git a/src/armTemplates/resources/functionApp.test.ts b/src/armTemplates/resources/functionApp.test.ts
index c0c12b9..3927442 100644
--- a/src/armTemplates/resources/functionApp.test.ts
+++ b/src/armTemplates/resources/functionApp.test.ts
@@ -45,6 +45,36 @@ describe("Function App Resource", () => {
   });
 
   describe("App Settings", () => {
+    describe("General", () => {
+      it("uses custom app insights instrumentation key", () => {
+        const instrumentationKey = "myInstrumentationKey"
+        const config = getConfig(FunctionAppOS.LINUX, Runtime.PYTHON36);
+        config.provider.appInsights = {
+          instrumentationKey,
+        }
+
+        const resource = new FunctionAppResource();
+        const { appSettings } = resource.getTemplate(config).resources[0].properties.siteConfig;
+        expect(appSettings).toEqual([
+          {
+            name: "FUNCTIONS_WORKER_RUNTIME",
+            value: "[parameters('functionAppWorkerRuntime')]"
+          },
+          {
+            name: "FUNCTIONS_EXTENSION_VERSION",
+            value: "[parameters('functionAppExtensionVersion')]"
+          },
+          {
+            name: "AzureWebJobsStorage",
+            value: "[concat('DefaultEndpointsProtocol=https;AccountName=',parameters('storageAccountName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2016-01-01').keys[0].value)]"
+          },
+          {
+            name: "APPINSIGHTS_INSTRUMENTATIONKEY",
+            value: instrumentationKey
+          }
+        ]);
+      });
+    })
     describe("Linux", () => {
       it("gets correct app settings - python", () => {
         const config = getConfig(FunctionAppOS.LINUX, Runtime.PYTHON36);