Skip to main content

Install .NET agents with Terraform

Use this procedure to install .NET Framework and .NET Core agents when using Terraform to deploy to Azure. You might need to customize this procedure for your environment.

Site extensions are the best way to deploy the Contrast agent to an Azure app service. You can only do this using the Azure Portal, an ARM policy, or the Azure API. The Terraform method described in this procedure uses the latter two methods directly or indirectly.

Before you begin

  • Verify that Contrast supports your preferred OS and runtime stack for the .NET Framework and .NET Core agents running in an Azure App Service:

  • Ensure you have met these requirements:

    • Login access to Contrast

    • Console access to a system where Terraform and the Azure CLI are installed

    • Login access to Azure Portal, including az login from the Azure CLI

    • Python is installed on the system where these commands are run

    • Included the Contrast agent as a part of Azure App Service

Step 1: Configure the agent

  1. Download a configuration file from Contrast:

    1. In the Contrast web interface, select Add New.

    2. Select the Application card.

    3. Follow the displayed instructions to get the required values and download a YAML configuration file.

  2. In the YAML configuration file, set the following values:

    • .NET Core agent

      CORECLR_ENABLE_PROFILING:1
      CORECLR_PROFILER:{8B2CE134-0948-48CA-A4B2-80DDAD9F5791}
      CORECLR_PROFILER_PATH_32:
       D:\\home\\SiteExtensions\\Contrast.NetCore.Azure.SiteExtension\\ContrastNetCoreAppService\\contrast\\runtimes\\win-x86\\native\\ContrastProfiler.dllCORECLR_PROFILER_PATH_64: D:\\home\\SiteExtensions\\Contrast.NetCore.Azure.SiteExtension\\ContrastNetCoreAppService\\\contrast\\runtimes\\win-x64\\native\\ContrastProfiler.dll
    • .NET Framework agent

      COR_ENABLE_PROFILING: 1
      COR_PROFILER: {EFEB8EE0-6D39-4347-A5FE-4D0C88BC5BC1}
      COR_PROFILER_PATH_32: D:\\home\\SiteExtensions\\Contrast.NET.Azure.SiteExtension\\ContrastAppService\\ContrastProfiler-32.dllCOR_PROFILER_PATH_64: D:\\home\\SiteExtensions\\Contrast.NET.Azure.SiteExtension\\ContrastAppService\\ContrastProfiler-64.dll

Step 2: Configure site extensions with Terraform

Because site extension deployment is only natively supported usingthe Azure portal, Azure ARM policies, and Azure API, Terraform is a convenient command line method to add or remove site extensions. It uses an ARM policy to set up the extension as shown in the examples.

Use this procedure to to instrument your application.

  1. Verify that the YAML configuration file you prepared in step 1 is named contrast_security.yaml.

  2. Install Terraform from here: https://www.terraform.io/downloads.html.

  3. Install PyYAML using this comand:

    pip install PyYAML
  4. Install the Azure CLI tools from this location: https://docs.microsoft.com/en-us/cli/azure/install-azure-cli

  5. Log in to Azure to make sure you cache your credentials using az login

  6. Use this parsing script parseyaml.py to pull values out of the Contrast YAML file and add them to the provisioned Azure App Service with this command:

    import yaml,
     jsonwith open('./contrast_security.yaml') as f:
        config = yaml.load(f)
        print(json.dumps(config['api']))
  7. Modify the Terraform document called main.tf as follows:

    provider "azurerm" {
      features {}
    }
    # Create a resource group
    resource "azurerm_resource_group" "personal" {
      name     = <name>
      location = <location>
    }
    # Create an app service plan
    resource "azurerm_app_service_plan" "app_service-plan"{
      name                = <name>
      resource_group_name = azurerm_resource_group.personal.name
      location            = <location>
    }
    # Create an app service
    resource "azurerm_app_service" "app_service" {
      name                = <name>
      location            = <location>
      resource_group_name = azurerm_resource_group.personal.name
      app_service_plan_id =azurerm_app_service_plan.app_service-plan.id
      site_config {
        dotnet_framework_version = "v4.0"
        default_documents        = ["Default.aspx"]
      }
    # CONTRAST .NET FRAMEWORK AGENT SETUP
    # Contrast env vars will be passed to the app service here.
      app_settings = {
        "COR_ENABLE_PROFILING"                    = "1"
        "COR_PROFILER"                            = "{EFEB8EE0-6D39-4347-A5FE-4D0C88BC5BC1}"
        "COR_PROFILER_PATH_32"                    = "D:\\home\\SiteExtensions\\Contrast.NET.Azure.SiteExtension\\ContrastAppService\\ContrastProfiler-32.dll"
        "COR_PROFILER_PATH_64"                    = "D:\\home\\SiteExtensions\\Contrast.NET.Azure.SiteExtension\\ContrastAppService\\ContrastProfiler-64.dll"
        "CONTRAST_INSTALL_DIRECTORY"              = "D:\\home\\SiteExtensions\\Contrast.NET.Azure.SiteExtension\\ContrastAppService\\"
        "CONTRAST__API__URL"                      = data.external.yaml.result.url 
        "CONTRAST__API__USER_NAME"                 = data.external.yaml.result.user_name
        "CONTRAST__API__SERVICE_KEY"              = data.external.yaml.result.service_key
        "CONTRAST__API__API_KEY"                  = data.external.yaml.result.api_key
        # USE THESE SETTING FOR .NET CORE AGENT
        #”CORECLR_ENABLE_PROFILING” = 1
        #”CORECLR_PROFILER”         = {8B2CE134-0948-48CA-A4B2-80DDAD9F5791}
        #”CORECLR_PROFILER_PATH_32” = D:\\home\\SiteExtensions\\Contrast.NetCore.Azure.SiteExtension\\ContrastNetCoreAppService\\contrast\\runtimes\\win-x86\\native\\ContrastProfiler.dll
        #”CORECLR_PROFILER_PATH_64” = D:\\home\\SiteExtensions\\Contrast.NetCore.Azure.SiteExtension\\ContrastNetCoreAppService\\\contrast\\runtimes\\win-x64\\native\\ContrastProfiler.dll
      }
    }
    #Extract the connection from the normal yaml file to pass to the app container
    data "external" "yaml" {
      program = [var.python_binary, "${path.module}/parseyaml.py"]
    }
    # Deploy the extension template
    resource "azurerm_template_deployment" "extension" {
      name                = <name>
      resource_group_name = <resource_group_name>
      template_body       = <<BODY
    {
       "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
       "contentVersion": "1.0.0.0",
       "parameters": {
           "siteName": {
               "type": "string",
               "metadata": {
                   "description": "The Azure App Service Name"
               }
           },
           "extensionName": {
               "type": "string",
               "metadata": {
                   "description": "The Site Extension Name."
               }
           }
       }, 
      "resources": [
           {
               "type": "Microsoft.Web/sites/siteextensions",
               "name": "[concat(parameters('siteName'),
    '/', parameters('extensionName'))]",
               "apiVersion": "2019-08-01",
               "location": "[resourceGroup().location]"
           }
       ]
    } 
      BODY  parameters = {
        "siteName"          = azurerm_app_service.<app_service>.name
        #.NET Framework
        "extensionName"     = "Contrast.NET.Azure.SiteExtension"
        #.NET Core
        # "extensionName"     = "Contrast.NetCore.Azure.SiteExtension" 
     }
      deployment_mode     = "Incremental"
    }