ARM Template - combining Application Gateway and enabling diagnostic logging into OMS

Introduction

Often times you are looking to go beyond the basic ARM template and as a Security/Infrastructure admin for the CORP's Azure deployment, your objective is to make sure Applications being deployed are following best practices some of which are:-
(a) Applications should be behind an Application Gateway (AppGW) combined/protected by a Web Application Firewall(WAF).
(b) Application should be funneling their diagnostic logs to an Operations Manager sink.
(c) Maybe other things from a security view point you can add.

Requirement

Application developers will deploy their applications and have infrastructure Code in the form of JSON templates OR the application owners hand over the Application code binaries and the infrastructure environment in the form of ARM template. Now you, the Azure Administrator, is responsible for securely deploying this application into the PROD environment, with the added requirements of Application security and logging. And you need to repeat this multiple times for multiple applications - so you need a template that combines the basic infrastructure the Application requires, plus a template to provision AppGW/WAF and combine with turning on diagnostic log and feed it into an OMS sink.

Implementation

You could use different techniques to do this. The first one that comes to mind is to create this from the portal in Azure and then reverse engineer the template out of the deployment. Unfortunately you cannot do that as of today (05/2017) as AppGW schema is not supported in the "Automation Script" - you will get the following error, when you try this reverse engineering route.

Application gateways cannot be exported yet and is not included in the template. See error details. The schema of resource type 'Microsoft.Network/applicationGateways' is not available. Resources of this type will not be exported to the template. (Code: ResourceTypeSchemaNotFound, Target: Microsoft.Network/applicationGateways)

So we are left with the taking AppGW template from one of the public repository and then combining it appropriately with the requisite JSON fragments for diagnostic settings, testing it, fixing errors till the deployment runs through completion. Then verify the actual deployment of the AppGW and the diagnostic settings persisted in the portal and as well as logs show up in the OMS sink.

Process

I essentially needed an AppGW template to start with. For this I used one from this link
Application Gateway Templates
Also the second ingredient required is the method for the diagnostic settings. The reference to this can be found in Templatizing diagnostic log settings

First fire up Visual Studio and then create a project of type "Azure Resource Group". Use a blank template and copy over one of your chosen AppGW based template. You could use one from the first link above OR use any other template you have for an Application Gateway.

vs-2017-05-08_22-02-37

 

Let me highlight some sections, that I had to figure out to get this to work.

The important thing is to add the resource specification for the diagnostic settings (in the second link above) correctly as a nested resource to the Application Gateway resource.

This is shown in the below graphic. Click on it to see a clearer view Nested resource for Diagnostics under an App-GW

As you can see in the graphic above, I have the primary resource "Application Gateway" and under it a nested resource of type "providers/diagnosticSettings" which depends on a resource of type "Microsoft.Network/applicationGateways".

"type": "providers/diagnosticSettings", "name": "Microsoft.Insights/service", "dependsOn": [ "[concat('Microsoft.Network/applicationGateways/', variables('applicationGatewayName'))]" ],

Parameter File

In my parameter file I already created the storage account and workspaceID which I then referred directly below. You could also use the JSON "depends" notation and create them dynamically if you so desired. In my case I chose to precreate them and refer them as parameters in my template, as I was mainly testing "HOW TO: Add the diagnostic log settings for an OMS sink into the main AppGW template.

{ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", "contentVersion": "1.0.0.0", "parameters": { "backendIpAddress1": { "value": "appGWIP1" }, "backendIpAddress2": { "value": "appGPIP2" }, "storageAccountName": {<br>"value": "myteststore321"<br>}, "workspaceId": {<br>"value": "/subscriptions/xxxx8775-d18a-45bb-abcd-3627de55xxxx/resourcegroups/mytest/providers/microsoft.operationalinsights/workspaces/mytestoms"<br>} } }

The full form of the main template is posted in the graphic below. To see it clearly click on the image and then hit "Ctrl +" in the browser Full Main Template