Agent installation guide
Overview
This guide offers best practices for using Contrast Security’s .NET Framework and .NET Core agents when using Terraform to deploy to Azure. We encourage you to take this guide, make it your own, and distribute it to teams who need to instrument applications this way.
Main steps
- Configure the agent
- Configure site extensions with Terraform to instrument the application
Supported technologies
Before you begin, please be sure Contrast supports your preferred OS and runtime stack for the .NET Framework and .NET Core agents running in an Azure App Service:
Supported technologies for .NET Framework
Supported technologies for .NET Core
This guide assumes you have:
- 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 installed on the system where these commands are run
- Previously included the Contrast agent as a part of Azure App Service. For more on this, read this related guide: [link to App Service guide]
Known issues
Site extensions are the best way to deploy the Contrast agent to an Azure app service, but this can only be done via the Azure Portal, an ARM policy, or the Azure API. The Terraform method described here will use the latter two methods directly or indirectly.
For more on using ARM policies and templates, read this related guide: [link to ARM guide]
Instructions
Begin by configuring the Contrast agent for your application.
1. Configure the agent
You will need to download a configuration file from Contrast. Begin by selecting Add Agent in Contrast and complete the steps indicated to get the values and download the .yaml configuration file.
We recommend setting at least the following values to configure the agent. Add these key/value pairs to the configuration file for the .NET agent you are using (copy the keys and values precisely):
.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.dll COR_PROFILER_PATH_64: D:\\home\\SiteExtensions\\Contrast.NET.Azure.SiteExtension\\ContrastAppService\\ContrastProfiler-64.dll
|
.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
|
2. Configure site extensions with Terraform
Because site extension deployment is only natively supported via the 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 here.
- Use the .yaml configuration file you prepared in step 1. Make sure it is named contrast_security.yaml
- Install Terraform from here: https://www.terraform.io/downloads.html.
- Install PyYAML using pip install PyYAML.
- Install the Azure CLI tools: https://docs.microsoft.com/en-us/cli/azure/install-azure-cli
- Log into Azure to make sure you cache your credentials using az login
- Use this parsing script parseyaml.py to pull values out of the Contrast .yaml file and add them to the provisioned Azure App Service
import yaml, json with open('./contrast_security.yaml') as f: config = yaml.load(f) print(json.dumps(config['api']))
|
- 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" }
|