How to Leverage ARM Templates in Azure for Intelligent Deployment

We previously showed in a blog post, The AppD Approach: Deployment Options for .NET Microservices Agent, how the advanced portability and refinement of AppDynamics’ new .NET Microservices Agent delivers great value to our customers who monitor .NET Core applications. Let’s dig further into how to deploy this agent following Infrastructure as Code (IaC) practices.

Azure Resource Manager (ARM) templates are an exciting framework for IaC. They allow you to create an entire environment from a simple template, with all the resources needed for your applications.

The ability to include the AppDynamics Site Extension as part of your ARM template deployment, however, introduces a few operational challenges, including:

  • How do you ensure your monitoring solution is installed only on specific environments?

  • Should you avoid creating a separate ARM template for each environment?

We can solve these challenges by putting the “Code” portion of IaC to work.

Condition is the Key

When working with ARM templates, It doesn’t take long for you to ask the question:

  • How do you deploy a resource based on a condition?

The Azure Resource Manager team answered with the condition attribute, which controls whether a resource will be deployed or not. If the condition check evaluates to “true,” the resource will be deployed. If not, the resource is skipped.

To enable the ARM template to be dynamic enough to deploy the AppDynamics Site Extension only when a condition evaluates to true, you must provide a parameter to contain your condition test, and add the condition attribute to your Site Extension resource.

Test Condition Parameter

"shouldInstallAppDynamicsExtension": {
  "type": "bool",
  "defaultValue": false,
  "metadata": {
    "description": "Conditional parameter to determine if AppDynamics Site Extension should be installed."
  }
}

Site Extension Resource with “condition” Attribute

{
    "apiVersion": "2015-08-01",
    "condition": "[parameters('shouldInstallAppDynamicsExtension')]",
    "name": "[parameters('appDynamicsSiteExtension')]",
    "type": "siteextensions",
    "dependsOn": [
    "[resourceId('Microsoft.Web/Sites/', variables('webSiteName'))]"
    ]
}

With the condition attribute added to your Site Extension resource, and a parameter waiting for you to give it a true or false value, you can easily determine—with a single template—when to deploy the AppDynamics Site Extension.

The next question becomes:

  • How can we configure the AppDynamics Site Extension automatically?

Object Parameters for the Win

One of the great options in ARM templates is the ability to create parameters of object type. This allows you to use a JSON object as a parameter value. Mix that capability with other ARM template magic, and you can easily configure the AppDynamics Site Extension without hard-coding any of template’s application settings.

AppDynamics Settings Object Type Parameter

"appDynamicsSettings": {
    "type": "object",
    "defaultValue": {
    "appdynamics.controller.hostName": "",
    "appdynamics.controller.port": "",
    "appdynamics.agent.accountName": "",
    "appdynamics.agent.accountAccessKey": "",
    "appdynamics.agent.applicationName": "",
    "appdynamics.controller.ssl.enabled": "",
    "appdynamics.agent.tierName": ""
    },
    "metadata": {
    "description": "Settings needed to get AppDynamics Site Extension configured."
    }
}

By setting the Application Settings Configuration Resource’s properties attribute value—the object type parameter for the AppDynamics Site Extension configuration—you can dynamically set the list of configuration settings without creating individual parameters for each setting. Then, as those settings change over time, your template doesn’t need to.

Application Settings Configuration Resource with Dynamic Properties

{
    "name": "appsettings",
    "type": "config",
    "apiVersion": "2015-08-01",
    "dependsOn": [
    "[resourceId('Microsoft.Web/sites', variables('webSiteName'))]"
    ],
    "tags": {
    "displayName": "appsettings"
    },
    "properties": "[parameters('appDynamicsSettings')]"
}

An important note about the Application Settings resource in an ARM template: it completely removes and replaces all the application settings in the App Service. If any application settings were manually added or changed after a deployment, they will be deleted.

The next challenge is determining how to configure your AppDynamics Site Extension configuration settings to deploy only when you deploy the Site Extension. Let’s explore how Template Functions can help with this.

To Union or Not to Union

One of the issues with the previous example—limiting the App Services application settings to only the AppDynamics parameter object—is that it doesn’t provides a place for adding additional settings. You can solve this issue by creating an object variable to contain the base application settings, and then figure out how to conditionally combine both groups of settings.

Object Variable to Define App Settings

variables": {
   "websiteName":"some-website-name"
   "appSettings": {
   "SomeRandomAppSetting": "Some Random Value"
   "AnotherRandomAppSetting": "Another Random Value"
   } 
}

ARM templates have a useful collection of functions to help make then more dynamic. To add the logic check for whether you should deploy the AppDynamics Site Extension configuration settings, you can use the if logical function and the union object function.

To begin, dynamically set the properties attribute by passing the previous condition test parameter—“shouldInstallAppDynamicsExtension”— to the if function. Based on that conditional check, you can then return a combination of the base “appSettings” variable and the “appDynamicsSettings” parameter with the union function, or just return the “appSettings” variable.

Conditionally Setting the Application Settings Properties Attribute

{
    "name": "appsettings",
    "type": "config",
    "apiVersion": "2015-08-01",
    "dependsOn": [
    "[resourceId('Microsoft.Web/sites', variables('webSiteName'))]"
    ],
    "tags": {
    "displayName": "appsettings"
    },
    "properties": "[if(parameters('shouldInstallAppDynamicsExtension'), union(variables('baseAppSettings'), parameters('appDynamicsSettings')), variables('baseAppSettings'))]"
}

Putting It All Together

You now have all the parts to dynamically deploy the AppDynamics Site Extension to an Azure App Service, based on a single boolean parameter. Let’s take a look at the ARM template as a whole.

The example below is a complete template for deploying a Hosting Plan (Service Plan), App Service (Web App), Application Settings for the App Service, and the Site Extension for the App Service. Included are the additional parameters and variables to enable the deployment of the AppDynamics Site Extension:

Complete ARM Template Example

{
 "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
 "contentVersion": "1.0.0.0",
 "parameters": {
"hostingPlanName": {
  "type": "string",
  "minLength": 1
},
"skuName": {
  "type": "string",
  "defaultValue": "F1",
  "allowedValues": [
    "F1",
    "D1",
    "B1",
    "B2",
    "B3",
    "S1",
    "S2",
    "S3",
    "P1",
    "P2",
    "P3",
    "P4"
  ],
  "metadata": {
    "description": "Describes plan's pricing tier and capacity. Check details at https://azure.microsoft.com/en-us/pricing/details/app-service/"
  }
},
"skuCapacity": {
  "type": "int",
  "defaultValue": 1,
  "minValue": 1,
  "metadata": {
    "description": "Describes plan's instance count"
  }
},
"appDynamicsSiteExtension": {
  "type": "string",
  "defaultValue": "AppDynamics.WindowsAzure.SiteExtension.4.4.Release",
  "allowedValues": [
    "AppDynamics.WindowsAzure.SiteExtension.4.4.Release",
    "AppDynamics.WindowsAzure.SiteExtension.4.3.Release",
    "AppDynamics.Java.Agent.4.4.Release"
  ],
  "metadata": {
    "description": "Full path name of the AppDynamics Site Extension to install."
  }
},
"shouldInstallAppDynamicsExtension": {
  "type": "bool",
  "defaultValue": false,
  "metadata": {
    "description": "Conditional parameter to determine if AppDynamics Site Extension should be installed."
  }
},
"appDynamicsSettings": {
  "type": "object",
  "defaultValue": {
    "appdynamics.controller.hostName": "",
    "appdynamics.controller.port": "",
    "appdynamics.agent.accountName": "",
    "appdynamics.agent.accountAccessKey": "",
    "appdynamics.agent.applicationName": "",
    "appdynamics.controller.ssl.enabled": "",
    "appdynamics.agent.tierName": ""
  },
  "metadata": {
    "description": "Settings needed to get AppDynamics Site Extension configured."
  }
}
 },
 "variables": {
"webSiteName": "[concat('some-webapp-', uniqueString(resourceGroup().id))]",
"appSettings": {
  "SomeRandomAppSetting": "Some Random Value",
  "AnotherRandomAppSetting": "Another Random Value"
},
 },
 "resources": [
{
  "apiVersion": "2015-08-01",
  "name": "[parameters('hostingPlanName')]",
  "type": "Microsoft.Web/serverfarms",
  "location": "[resourceGroup().location]",
  "tags": {
    "displayName": "HostingPlan"
  },
  "sku": {
    "name": "[parameters('skuName')]",
    "capacity": "[parameters('skuCapacity')]"
  },
  "properties": {
    "name": "[parameters('hostingPlanName')]"
  }
},
{
  "apiVersion": "2015-08-01",
  "name": "[variables('webSiteName')]",
  "type": "Microsoft.Web/sites",
  "location": "[resourceGroup().location]",
  "tags": {
    "[concat('hidden-related:', resourceGroup().id, '/providers/Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]": "Resource",
    "displayName": "Website"
  },
  "dependsOn": [
    "[resourceId('Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]"
  ],
  "properties": {
    "name": "[variables('webSiteName')]",
    "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('hostingPlanName'))]"
  },
  "resources": [
    {
      "name": "appsettings",
      "type": "config",
      "apiVersion": "2015-08-01",
      "dependsOn": [
        "[resourceId('Microsoft.Web/sites', variables('webSiteName'))]"
      ],
      "tags": {
        "displayName": "appsettings"
      },
      "properties": "[if(parameters('shouldInstallAppDynamicsExtension'), union(variables('appSettings'), parameters('appDynamicsSettings')), variables('appSettings'))]"
    },
    {
      "apiVersion": "2015-08-01",
      "condition": "[parameters('shouldInstallAppDynamicsExtension')]",
      "name": "[parameters('appDynamicsSiteExtension')]",
      "type": "siteextensions",
      "dependsOn": [
        "[resourceId('Microsoft.Web/Sites/', variables('webSiteName'))]"
      ]
      }
  ]
}
 ]
}

Stayed Tuned for More on ARM Templates

I hope these steps have given you an overview of Azure Resource Manager (ARM) templates, and how to leverage them for intelligent deployment of the AppDynamics Site Extension. In my next blog, I’ll show how to use the ARM template in a release plan on Visual Studio Team Services (VSTS) to configure and deploy a sample Azure App Service with the AppDynamics Site Extension.


Learn more to understand the big picture of AppDynamics’ seamless integration with Microsoft Azure.

Diving Into What’s New in Java & .NET Monitoring

In the AppDynamics Spring 2014 release we added quite a few features to our Java and .NET APM solutions. With the addition of the service endpoints, an improved JMX console, JVM crash detection and crash reports, additional support for many popular frameworks, and async support we have the best APM solution in the marketplace for Java and .NET applications.

Added support for frameworks:

  • TypeSafe Play/Akka

  • Google Web Toolkit

  • JAX-RS 2.0

  • Apache Synapse

  • Apple WebObjects

Service Endpoints

With the addition of service endpoints customers with large SOA environments can define specific service points to track metrics and get associated business transaction information. Service endpoints helps service owners monitor and troubleshoot their own specific services within a large set of services:

JMX Console

The JMX console has been greatly improved to add the ability to manage complex attributes and provide executing mBean methods and updating mBean attributes:

JVM Crash Detector

The JVM crash detector has been improved to provide crash reports with dump files that allow tracing the root cause of JVM crashes:

Async Support

We  added improved support for asynchronous calls and added a waterfall timeline for better clarity in where time is spent during requests:

  

AppDynamics for .NET applications has been greatly improved by adding better integration and support for Windows AzureASP.Net MVC 5, improved Windows Communication Foundation support, and RabbitMQ support:

 

 

Take five minutes to get complete visibility into the performance of your production applications with AppDynamics today.

Instrumenting .NET applications with AppDynamics using NuGet

Introduction

One of the coolest things to come out of the .NET stable at AppD this week was the NuGet package for Azure Cloud Services. NuGet makes it a breeze to deploy our .NET agent along with your web and worker roles from inside Visual Studio. For those unfamiliar with NuGet, more information can be found here.

Our NuGet package ensures that the .NET agent is deployed at the same time when the role is published to the cloud. After adding it to the project you’ll never have to worry about deploying the agent when you swap your hosting environment from staging to production in Azure or when Azure changes the machine from under your instance. For the remainder of the post I’ll use a web role to demonstrate how to quickly install our NuGet package, changes it makes to your solution and how to edit the configuration by hand if needed. Even though I’ll use a web role, things work exactly the same way for a worker role.

Installation

So, without further ado, let’s take a look at how to quickly instrument .NET code in Azure using AppD’s NuGet package for Windows Azure Cloud Services. NuGet packages can be added via the command line or the GUI. In order to use the command line, we need to bring up the package manager console in Visual Studio as shown below

PackageManager

In the console, type ‘install-package AppDynamics.WindowsAzure.CloudServices’ to install the package. This will bring up the following UI where you can enter the information needed by the agent to talk to the controller and upload metrics. You should have received this information in the welcome email from AppDynamics.

Azure

The ‘Application Name’ is the name of the application in the controller under which the metrics reported by this agent will be stored. When ‘Test Connection’ is checked we will check the information entered by trying to connect to the controller. An error message will be displayed if the test connection is unsuccessful. That’s it, enter the information, click apply and we’re done. Easy Peasy. No more adding files one by one or modifying scripts by hand. Once deployed, instances of this web role will start reporting metrics as soon as they experience any traffic. Oh, and by the way, if you prefer to use a GUI instead of typing commands on the console, the same thing can be done by right-clicking on the solution in Visual Studio and choosing ‘Manage NuGet Package’.

Anatomy of the package

If you look closely at the solution explorer you’ll notice that a new folder called ‘AppDynamics’ has been created in the solution explorer. On expanding the folder you’ll find the following two files:

  • Installer of the latest and greatest .NET agent.
  • Startup.cmd
The startup script makes sure that the agent gets installed as a part of the deployment process on Azure. Other than adding these files we also change the ServiceDefinition.csdef file to add a startup task as shown below.

Screen Shot 2013-11-27 at 8.11.27 PM

In case, you need to change the controller information you entered in the GUI while installing the package, it can be done by editing the startup section of the csdef file shown above. Application name, controller URL, port, account key etc. can all be changed. On re-deploying the role to Azure, these new values will come into effect.

Next Steps

Microsoft Developer Evangelist, Bruno Terkaly blogged about monitoring the performance of multi-tiered Windows Azure based web applications. Find out more on Microsoft Developer Network.

Find out more in our step-by-step guide on instrumenting .NET applications using AppDynamics Pro. Take five minutes to get complete visibility into the performance of your production applications with AppDynamics Pro today.

As always, please feel free to comment if you think I have missed something or if you have a request for content in an upcoming post.

AppDynamics Pro on the Windows Azure Store

Over a year ago, AppDynamics announced a partnership with Microsoft and launched AppDynamics Lite on the Windows Azure Store. With AppDynamics Lite, Windows Azure users were able to easily monitor their applications at the code level, allowing them to identify and diagnose performance bottlenecks in real time. Today we’re happy to announce that AppDynamics Pro is now available as an addon in the Windows Azure store, which makes it easier for developers to get complete visibility into their mission-critical applications running on Windows Azure.

  • Easier/simplified buying experience in Windows Azure Store
  • Tiered pricing based on number of agents and VM size
  • Easy deployment from Visual Studio with NuGet
  • Out-of-the-box support for more Windows Azure services

“AppDynamics is one of only a handful of application monitoring solutions that works on Windows Azure, and the only one that provides the level of visibility required in our distributed and complex application environments,” said James Graham, project manager at MacMillan Publishers. “The AppDynamics monitoring solution provides insight into how our .NET applications perform at a code level, which is invaluable in the creation of a dynamic, fulfilling user experience for our students.”

Easy buying experience

Purchasing the AppDynamics Pro add-on in the Windows Azure Store only takes a couple of minutes. In the Azure portal click NEW at the bottom left of the screen and then select STORE. Search for AppDynamics, choose your plan, add-on name and region.

4-choose-appdynamics

Tiered pricing

AppDynamics Pro for Windows Azure features new tiered pricing based on the size of your VM (extra small, small or medium, large, or extra large) and the number of agents required (1, 5 or 10). This new pricing allows organizations with smaller applications to pay less to store their monitoring data than those with larger, more heavily trafficked apps. The cost is added to your monthly Windows Azure bill, and you can cancel or change your plan at any time.

AppDynamics on Windows Azure Pricing

Deploying with NuGet

Use the AppDynamics NuGet package to deploy AppDynamics Pro with your solution from Visual Studio. For detailed instructions check out the how-to guide.

2-vs-package-search

Monitoring with AppDynamics

  • Monitor the health of Windows Azure applications
  • Troubleshoot performance problems in real time
  • Rapidly diagnose root cause of performance problems
  • Dynamically scale up and scale down their Windows Azure application based on performance metrics

AppDynamics .Net App

Additional platform support

AppDynamics Pro automatically detects and monitors most Azure services out-of-the-box, including web and worker roles, SQL, Azure Blob, Azure Queue and Windows Azure Service Bus. In addition, AppDynamics Pro now supports MVC 4. Find out more in our getting started guide for Windows Azure.

Get started monitoring your Windows Azure app by adding the AppDynamics Pro add-on in the Windows Azure Store.

Cloud Migration won’t happen overnight

There is a massive difference between migrating some code to the cloud and migrating an entire application to the cloud. Yes, the heart of any application is indeed its codebase, but code can’t execute without data and there lies the biggest challenge of any cloud migration. “No problem,” you say. “We can just move our database to the cloud and our code will be able to access it.” Sounds great, apart from most storage services in the cloud tend to run on cheap disk which is often virtualized and shared across several tenants. It’s no secret that databases store and access data from disk; the problem these days is that disks have got bigger and cheaper, but they haven’t exactly got much faster. The assumption that Cloud will offer your application a better Quality of Service (QoS) at a cheaper price is therefore not always true when you include application tiers that manage data. Your code might run faster with cheaper and elastic computing power, but it can only go as fast as the data which it retrieves and processes.

.NET Application Performance delivered with AppDynamics 3.3

It’s official: AppDynamics support for Microsoft .NET and Windows Azure is finally here! We’ve got the same Kick Ass Product with the same Secret Sauce–but now it sports a shiny new CLR agent. So whether your apps are Java,  .NET or hybrid, with AppDynamics you have the best of both worlds when it comes to managing application performance.

We thought it was only fair to share our secret sauce and love with the Microsoft community, given that 40,000+ users of the Java community have been enjoying it for over 18 months. Our mission is to simplify the way organizations manage their agile, complex, and distributed applications. For .NET, this means that AppDynamics supports the latest and greatest technologies from Microsoft, including their new PaaS platform Windows Azure.

So, what does this mean for organizations with .NET or Azure apps? Let me summarize:

#1 You get to visualize in real-time what your .NET application actually looks like, along with its health and performance across any distributed production environment. It’s the 50,000 foot view that shows how your application and your business performs in your data center or Windows Azure.

#2 Ability to track all business transactions that flow through your .NET application. This gives you insight into business activity, health, and impact in the event that a slowdown or problem occurs in your production environment. This unique context and visibility helps you troubleshoot through the eyes of the business, so you can see their pain instantly in production and resolve it in minutes. We auto-discover and map every business transaction automatically–so don’t worry about configuration. We’ve got that taken care of.

 

#3 Deep diagnostic information on how your business transactions actually execute through your CLRs and/or JVMs (if you’ve got a hybrid app). This means complete call stacks of code execution with latency breakdowns across all your namespaces, classes and methods, which your business transactions invoke. You get maximum visibility in production with zero configuration, allowing you to perform root cause analysis in minutes.

#4 Ability to plot, correlate, and trend any CLR or OS metric over time–whether it’s logic thread counts, garbage collection time, or simply how much CPU your application CLR is burning. We let you report and analyze all this so you understand your CLR run-time and OS system resource.

Don’t believe us? Sign up for our free 30-day trial and we’ll provision you a SaaS login. You can then download and install our lightweight agents and see for yourself just how easy it can be!

As well as our .NET support, we’ve also crammed in some great innovation into the 3.3 release.

Real-Time JVM MBean Viewer:

In addition to trending standard JMX metrics from the JVM, users can now discover and trend any MBean attributes on the fly for short term analysis in real-time. Our new UI dialogue allows the user to browse through hundreds of available metrics which are automatically discovered and reported at the touch of a button. If the user wishes to convert any MBean attribute into a standard JMX metric they can just click “Create Metric” and AppDynamics will collect and report that metric as standard in the JMX Metrics viewer.

Search Business Transactions by their content/payload:

For example, you might have launched a new product on your application or website and need to understand its performance by looking at all business transactions that interact with that product. With AppDynamics v3.3 users can now search business transactions by any transaction payload. For example, the below screenshot shows how a user can search for all business transactions that relate to the book “Harry Potter”.

Additional Platform Support:

  • Auto-discovery and mapping of LDAP, SAP and JavaMail tiers to business transaction flows for increased visibility.
  • MongoDB support allowing users to see BSON queries and associated latency for calls made from Java applications.
  • Enhanced support for WebSphere on Z/OS with automatic JVM naming pools to help customers identify and manage short-living and dynamic JVM run-times.
All in all another great release packed full of innovation from the AppDynamics team. Stay tuned over the next few weeks for more information on specific 3.3 features.
App Man.