Authenticate system assigned identity to Event Grid API connection - azure

Can anyone help me find the client secret for a system assigned identity in an ARM template, or suggest an alternative approach?
I've got an ARM template which creates a Logic App with system assigned identity, and now I want to set up an API connection to trigger from Event Grid (without using the portal UI or a separate powershell command).
I can't figure out how to get the client secret for the system assigned identity. This would allow me to follow the answers in these previous questions:
Create API Connection for Azure Data Factory with service principal authentication using ARM Template
How to authenticate an Azure EventGrid API Connection using a script?
Here's what I have so far:
"resources": [
{
"apiVersion": "2016-06-01",
"type": "Microsoft.logic/workflows",
"name": "[variables('logicName')]",
"location": "[resourceGroup().location]",
"identity": {
"type": "SystemAssigned"
},
"dependsOn": [
"[variables('connections_azuretables_name')]"
],
"properties": {
"state": "Enabled",
"definition": {
<<SNIP>>
}
}
},
{
"type": "Microsoft.Web/connections",
"apiVersion": "2016-06-01",
"name": "[variables('azureEventGridConnectionAPIName')]",
"location": "[resourceGroup().location]",
"properties": {
"api": {
"id": "[concat('/subscriptions/subscriptionId', '/providers/Microsoft.Web/locations/', 'eastasia', '/managedApis/', 'azureeventgrid')]"
},
"parameterValues": {
"token:clientId": "[reference(variables('logicName'), '2016-06-01', 'Full').identity.principalId]",
"token:clientSecret": "########### STUCK HERE #################",
"token:TenantId": "[reference(variables('logicName'), '2016-06-01', 'Full').identity.tenantId]",
"token:grantType": "client_credentials"
},
"displayName": "[variables('azureEventGridConnectionAPIName')]"
},
"dependsOn": []
}
],

A managed identity has no client secret. It only has certificates, which you cannot access.
The template would have to execute within the logic app to get the access token, which I doubt it can do.

For anyone wondering, it is pretty straightforward to create a Service Principal manually and then feed it into the ARM template:
> az ad sp create-for-rbac --name MyPrincipal
{
"appId": "##############",
"displayName": "MyPrincipal",
"name": "http://MyPrincipal",
"password": "##############",
"tenant": "##############"
}
Now pass the appId (as clientId) password (as clientSecret) and tenant (as tenantId) into the parameterValues block in Microsoft.Web/connections. This will set up an Event Grid API connection for your logic app, but with implications for access policies and overhead of identity management outside of the ARM template.
The actual solution I've used is to create a webhook event subscription on Event Grid and then set up my logic app to have a web hook trigger. This works just fine.
Here's a sample solution:
{
"name": "[parameters('topicName')]",
"type": "Microsoft.EventGrid/topics",
"location": "[resourceGroup().location]",
"apiVersion": "2018-01-01",
"properties": { }
},
{
"name": "[concat(parameters('topicName'), '/Microsoft.EventGrid/', variables('topicSubscriptionName'))]",
"type": "Microsoft.EventGrid/topics/providers/eventSubscriptions",
"location": "[resourceGroup().location]",
"apiVersion": "2018-01-01",
"properties": {
"destination": {
"endpointType": "WebHook",
"properties": {
"endpointUrl": "[listCallbackURL(resourceId('Microsoft.Logic/workflows/triggers', parameters('logicName'), 'WorkaroundWebhookTrigger'), '2016-06-01').value]"
}
},
"filter": {
"includedEventTypes": [
"All"
]
}
},
"dependsOn": [
"[parameters('topicName')]",
"[parameters('logicName')]"
]
},
{
"apiVersion": "2016-06-01",
"type": "Microsoft.logic/workflows",
"name": "[parameters('logicName')]",
"location": "[resourceGroup().location]",
"identity": {
"type": "SystemAssigned"
},
"dependsOn": [],
"properties": {
"state": "Enabled",
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"$connections": {
"defaultValue": {},
"type": "Object"
}
},
"triggers": {
"WorkaroundWebhookTrigger": {
"type": "Request",
"kind": "Http",
"inputs": {
"schema": {
"properties": {
"data": {
"properties": {
"lorem": {
"type": "integer"
},
"ipsum": {
"type": "string"
}
},
"type": "object"
},
"dataVersion": {
"type": "string"
},
"eventTime": {
"type": "string"
},
"eventType": {
"type": "string"
},
"id": {
"type": "string"
},
"metadataVersion": {
"type": "string"
},
"subject": {
"type": "string"
},
"topic": {
"type": "string"
}
},
"type": "object"
}
}
}
},
<snip>

Related

Azure resources created using custom provider not showing on azure portal

I created an Azure custom provider by following the documentation in the link below:
https://learn.microsoft.com/en-us/azure/azure-resource-manager/custom-providers/
I am able to successfully create resources for the types defined in the custom provider using ARM templates. However, I do not see those resources on the azure portal under the specific resource group.
Is this behavior expected?
I have deployed the custom provider in azure portal using ARM template by following below steps
Open azure portal and search for custom deployment as below
Taken reference from Microsoft Doc
After opening custom deployment, i have used the below code and then click on save
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"funcName": {
"type": "string",
"defaultValue": "[uniqueString(resourceGroup().id)]",
"metadata": {
"description": "The unique name of the function application"
}
},
"storageName": {
"type": "string",
"defaultValue": "[concat('store', uniquestring(resourceGroup().id))]",
"metadata": {
"description": "The unique name of the storage account."
}
},
"location": {
"type": "string",
"defaultValue": "eastus",
"metadata": {
"description": "The location for the resources."
}
},
"zipFileBlobUri": {
"type": "string",
"defaultValue": "https://github.com/Azure/azure-docs-json-samples/blob/master/custom-providers/_artifacts/functionpackage.zip?raw=true",
"metadata": {
"description": "The URI to the uploaded function zip file"
}
}
},
"resources": [
{
"type": "Microsoft.Web/sites",
"apiVersion": "2022-03-01",
"name": "[parameters('funcName')]",
"location": "[parameters('location')]",
"kind": "functionapp",
"identity": {
"type": "SystemAssigned"
},
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', parameters('storageName'))]"
],
"properties": {
"name": "[parameters('funcName')]",
"siteConfig": {
"appSettings": [
{
"name": "AzureWebJobsDashboard",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=',parameters('storageName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageName')), '2022-05-01').keys[0].value)]"
},
{
"name": "AzureWebJobsStorage",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=',parameters('storageName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageName')), '2022-05-01').keys[0].value)]"
},
{
"name": "FUNCTIONS_EXTENSION_VERSION",
"value": "~2"
},
{
"name": "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=',parameters('storageName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageName')), '2022-05-01').keys[0].value)]"
},
{
"name": "WEBSITE_CONTENTSHARE",
"value": "[toLower(parameters('funcName'))]"
},
{
"name": "WEBSITE_NODE_DEFAULT_VERSION",
"value": "6.5.0"
},
{
"name": "WEBSITE_RUN_FROM_PACKAGE",
"value": "[parameters('zipFileBlobUri')]"
}
]
},
"clientAffinityEnabled": false,
"reserved": false
}
},
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2022-05-01",
"name": "[parameters('storageName')]",
"location": "[parameters('location')]",
"kind": "StorageV2",
"sku": {
"name": "Standard_LRS"
}
},
{
"type": "Microsoft.CustomProviders/resourceProviders",
"apiVersion": "2018-09-01-preview",
"name": "[parameters('funcName')]",
"location": "[parameters('location')]",
"dependsOn": [
"[concat('Microsoft.Web/sites/',parameters('funcName'))]"
],
"properties": {
"actions": [
{
"name": "ping",
"routingType": "Proxy",
"endpoint": "[concat('https://', parameters('funcName'), '.azurewebsites.net/api/{requestPath}')]"
}
],
"resourceTypes": [
{
"name": "users",
"routingType": "Proxy,Cache",
"endpoint": "[concat('https://', parameters('funcName'), '.azurewebsites.net/api/{requestPath}')]"
}
]
}
},
{
"type": "Microsoft.CustomProviders/resourceProviders/users",
"apiVersion": "2018-09-01-preview",
"name": "[concat(parameters('funcName'), '/ana')]",
"location": "parameters('location')",
"dependsOn": [
"[concat('Microsoft.CustomProviders/resourceProviders/',parameters('funcName'))]"
],
"properties": {
"FullName": "Ana Bowman",
"Location": "Moon"
}
}
],
"outputs": {
"principalId": {
"type": "string",
"value": "[reference(concat('Microsoft.Web/sites/', parameters('funcName')), '2022-03-01', 'Full').identity.principalId]"
}
}
}
Fill the following details like Subscription id, resource group, location and click on review+create
After deploying into the azure portal, we will get below
After deploying it to azure poral Goto azure portal and click on your resource group and click on the check box you will find as below

How can I add an azure function to an API Management using ARM template

I'm using this ARM template to add an external Azure function (already defined in other template) to my API management but I get a validation error (resource is not defined in template). Is there any solution to automate mapping azure function with an API management?
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {...},
"resources": [
{
"apiVersion": "2017-03-01",
"name": "[parameters('apiManagementServiceName')]",
"type": "Microsoft.ApiManagement/service",
"location": "[parameters('location')]",
"tags": {},
"sku": {
"name": "[parameters('sku')]",
"capacity": "[parameters('skuCount')]"
},
"properties": {
"publisherEmail": "[parameters('publisherEmail')]",
"publisherName": "[parameters('publisherName')]"
}
},
{
"type": "Microsoft.ApiManagement/service/apis",
"apiVersion": "2018-06-01-preview",
"name": "[concat(parameters('apiManagementServiceName'), '/', parameters('indexerApp'))]",
"dependsOn": [
"[resourceId('Microsoft.ApiManagement/service', parameters('apiManagementServiceName'))]",
"[resourceId(resourceGroup().name, 'Microsoft.Web/sites', parameters('indexerApp'))]"
],
"properties": {
"displayName": "[parameters('indexerApp')]",
"apiRevision": "1",
"description": "Import from \"[parameters('indexerApp')]\" Function App",
"path": "[parameters('indexerApp')]",
"protocols": [
"https"
]
}
}
]
}
The resource that links directly to a Logic App, Function or other internal Azure resource is a backends (note plural):
{
"name": "string",
"type": "Microsoft.ApiManagement/service/backends",
"apiVersion": "2019-01-01",
"properties": {
"title": "string",
"description": "string",
"resourceId": "string",
"properties": {
"serviceFabricCluster": {
"clientCertificatethumbprint": "string",
"maxPartitionResolutionRetries": "integer",
"managementEndpoints": [
"string"
],
"serverCertificateThumbprints": [
"string"
],
"serverX509Names": [
{
"name": "string",
"issuerCertificateThumbprint": "string"
}
]
}
},
"credentials": {
"certificate": [
"string"
],
"query": {},
"header": {},
"authorization": {
"scheme": "string",
"parameter": "string"
}
},
"proxy": {
"url": "string",
"username": "string",
"password": "string"
},
"tls": {
"validateCertificateChain": "boolean",
"validateCertificateName": "boolean"
},
"url": "string",
"protocol": "string"
}
}
I believe that if you specify the resourceId property, the Azure infrastructure automatically wires up the other properties to your Function (or Logic App). The format of the "id" is not obvious, it expects a Management URI, the format of which is mentioned in this documentation
You then link this created backends to an operation using the operation's policy - this is a pain to express in ARM templates, but it should contain a policy expression:
<set-backend-service backend-id=\"[name of your backend]\"/>
An example of how these are linked together can be found at this linked sample. It features Service Fabric but it should be generally applicable to Functions as well.

Using CopyIndex and listKeys in outputs section

I'm trying to get the primaryConnectionStrings from an aRM template that creates multiple notification hubs
But I get this error
Error: Code=InvalidTemplate; Message=Deployment template validation failed: 'The template output 'connectionStrings' at line '291' and column '30' is not valid: The
template function 'copyIndex' is not expected at this location. The function can only be used in a resource with copy specified. Please see https://aka.ms/arm-copy for usage details.. Please see
https://aka.ms/arm-template-expressions for usage details.'.
I am clearly missing what this actually means as I've tried various incarnations of the template all of which have a copy for the resource.
I've tried this with a nested template (apologies if i've mangled the template, just removed some extraneous items):
"resources": [
{
"type": "Microsoft.NotificationHubs/namespaces",
"apiVersion": "2017-04-01",
"name": "[parameters('notificationHubName')]",
"location": "[resourceGroup().location]",
"tags": {
"Environment": "[parameters('environment')]",
"DisplayName": "Notification Hub Namespace"
},
"sku": {
"name": "[parameters('notificationHubSku')]"
},
"kind": "NotificationHub",
"properties": {
"namespaceType": "NotificationHub"
}
},
{
"type": "Microsoft.NotificationHubs/namespaces/AuthorizationRules",
"apiVersion": "2017-04-01",
"name": "[concat(parameters('notificationHubName'), '/RootManageSharedAccessKey')]",
"tags": {
"Environment": "[parameters('environment')]",
"DisplayName": "Notification Hub Namespace Auth Rules"
},
"dependsOn": [
"[resourceId('Microsoft.NotificationHubs/namespaces', parameters('notificationHubName'))]"
],
"properties": {
"rights": [
"Listen",
"Manage",
"Send"
]
}
},
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2018-05-01",
"name": "[concat('nestedTemplate', copyIndex('notificationHubEntities'))]",
"copy": {
"name": "notificationHubEntities",
"count": "[length(parameters('notificationHubEntities'))]"
},
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"type": "Microsoft.NotificationHubs/namespaces/notificationHubs",
"apiVersion": "2017-04-01",
"name": "[concat(parameters('notificationHubName'), '/', parameters('notificationHubEntities')[copyIndex('notificationHubEntities')])]",
"location": "[resourceGroup().location]",
"tags": {
"Environment": "[parameters('environment')]",
"DisplayName": "Notification Hubs"
},
"dependsOn": [
"[resourceId('Microsoft.NotificationHubs/namespaces', parameters('notificationHubName'))]"
],
"properties": {
"authorizationRules": []
}
},
{
"type": "Microsoft.NotificationHubs/namespaces/notificationHubs/authorizationRules",
"apiVersion": "2017-04-01",
"name": "[concat(parameters('notificationHubName'), '/',parameters('notificationHubEntities')[copyIndex('notificationHubEntities')],'/DefaultFullSharedAccessSignature')]",
"tags": {
"Environment": "[parameters('environment')]",
"DisplayName": "Notification Hub Auth Rules"
},
"dependsOn": [
"[resourceId('Microsoft.NotificationHubs/namespaces/notificationHubs',parameters('notificationHubName'), parameters('notificationHubEntities')[copyIndex('notificationHubEntities')])]",
"[resourceId('Microsoft.NotificationHubs/namespaces', parameters('notificationHubName'))]"
],
"properties": {
"rights": [
"Listen",
"Manage",
"Send"
]
}
},
],
"outputs" : {
"connectionString" : {
"type" : "object",
"value": "[listKeys(resourceId('Microsoft.NotificationHubs/namespaces/NotificationHubs/AuthorizationRules',parameters('notificationHubName'), parameters('notificationHubEntities')[copyIndex('notificationHubEntities')], 'DefaultFullSharedAccessSignature'),'2016-03-01').primaryConnectionString]"
}
}
}
}
}
],
"outputs": {
"connectionStrings" :
{
"type": "array",
"value": "[reference(concat('nestedTemplate', copyIndex('notificationHubEntities'))).outputs.connectionString.value]"
}
}
}
I've also tried with this:
"resources": [
{
"type": "Microsoft.NotificationHubs/namespaces",
"apiVersion": "2017-04-01",
"name": "[parameters('notificationHubName')]",
"location": "[resourceGroup().location]",
"tags": {
"Environment": "[parameters('environment')]",
"DisplayName": "Notification Hub Namespace"
},
"sku": {
"name": "[parameters('notificationHubSku')]"
},
"kind": "NotificationHub",
"properties": {
"namespaceType": "NotificationHub"
}
},
{
"type": "Microsoft.NotificationHubs/namespaces/AuthorizationRules",
"apiVersion": "2017-04-01",
"name": "[concat(parameters('notificationHubName'), '/RootManageSharedAccessKey')]",
"tags": {
"Environment": "[parameters('environment')]",
"DisplayName": "Notification Hub Namespace Auth Rules"
},
"dependsOn": [
"[resourceId('Microsoft.NotificationHubs/namespaces', parameters('notificationHubName'))]"
],
"properties": {
"rights": [
"Listen",
"Manage",
"Send"
]
}
},
{
"type": "Microsoft.NotificationHubs/namespaces/notificationHubs",
"apiVersion": "2017-04-01",
"name": "[concat(parameters('notificationHubName'), '/', parameters('notificationHubEntities')[copyIndex()])]",
"location": "[resourceGroup().location]",
"tags": {
"Environment": "[parameters('environment')]",
"DisplayName": "Notification Hubs"
},
"copy": {
"name": "addNotificationHub",
"count": "[length(parameters('notificationHubEntities'))]"
},
"dependsOn": [
"[resourceId('Microsoft.NotificationHubs/namespaces', parameters('notificationHubName'))]"
],
"properties": {
"authorizationRules": []
}
},
{
"type": "Microsoft.NotificationHubs/namespaces/notificationHubs/authorizationRules",
"apiVersion": "2017-04-01",
"name": "[concat(parameters('notificationHubName'), '/',parameters('notificationHubEntities')[copyIndex()],'/DefaultFullSharedAccessSignature')]",
"copy": {
"name": "addNotificationHub",
"count": "[length(parameters('notificationHubEntities'))]"
},
"tags": {
"Environment": "[parameters('environment')]",
"DisplayName": "Notification Hub Auth Rules"
},
"dependsOn": [
"[resourceId('Microsoft.NotificationHubs/namespaces/notificationHubs',parameters('notificationHubName'), parameters('notificationHubEntities')[copyIndex()])]",
"[resourceId('Microsoft.NotificationHubs/namespaces', parameters('notificationHubName'))]"
],
"properties": {
"rights": [
"Listen",
"Manage",
"Send"
]
}
}
],
"outputs": {
"connectionStrings" :
{
"type": "array",
"value": "[listKeys(resourceId('Microsoft.NotificationHubs/namespaces/NotificationHubs/AuthorizationRules',parameters('notificationHubName'), parameters('notificationHubEntities')[copyIndex()], 'DefaultFullSharedAccessSignature'),'2016-03-01').primaryConnectionString]"
}
}
I've tried using object instead of array but to no avail, so I'm a bit confused, any help would be appreciated as the error message seems misleading to me or I'm just not interpreting it correctly.
To accomplish requirement of creating multiple notification hubs and it's authorization rules, you can use below ARM template.
Template Parameter File (notificationhub.parameters.json):
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"namespaceName": {
"value": "mm-namespace"
},
"notificationhubNamePrefix": {
"value": "mm-notificationhub"
},
"notificationhubAuthorizationruleNamePrefix": {
"value": "mm-notificationhubAuthorizationrule"
}
}
}
Template File (notificationhub.json):
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"namespaceName": {
"type": "string",
"defaultValue": "mm-namespace",
"metadata": {
"description": "namespaceName sample description"
}
},
"notificationhubNamePrefix": {
"type": "string",
"defaultValue": "mm-notificationhub",
"metadata": {
"description": "notificationhubName sample description"
}
},
"notificationhubAuthorizationruleNamePrefix": {
"type": "string",
"defaultValue": "mm-notificationhubAuthorizationrule",
"metadata": {
"description": "notificationhubAuthorizationruleName sample description"
}
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "The location in which the resources should be deployed."
}
},
"notificationhubNameSuffix": {
"type": "array",
"defaultValue": [
"00",
"01",
"02"
]
},
"notificationhubAuthorizationruleNameSuffix": {
"type": "array",
"defaultValue": [
"00",
"01",
"02"
]
}
},
"variables": {},
"resources": [
{
"name": "[parameters('namespaceName')]",
"type": "Microsoft.NotificationHubs/namespaces",
"apiVersion": "2017-04-01",
"location": "[parameters('location')]",
"tags": {},
"sku": {
"name": "Free"
},
"properties": {
"namespaceType": "NotificationHub"
}
},
{
"name": "[concat(parameters('namespaceName'), '/', parameters('notificationhubNamePrefix'), parameters('notificationhubNameSuffix')[copyIndex()])]",
"type": "Microsoft.NotificationHubs/namespaces/notificationHubs",
"apiVersion": "2017-04-01",
"location": "[parameters('location')]",
"sku": {
"name": "Free"
},
"copy": {
"name": "notificationhubscopy",
"count": "[length(parameters('notificationhubNameSuffix'))]"
},
"dependsOn": [
"[resourceId('Microsoft.NotificationHubs/namespaces', parameters('namespaceName'))]"
]
},
{
"name": "[concat(parameters('namespaceName'), '/', parameters('notificationhubNamePrefix'), parameters('notificationhubNameSuffix')[copyIndex()], '/', parameters('notificationhubAuthorizationruleNamePrefix'), parameters('notificationhubAuthorizationruleNameSuffix')[copyIndex()])]",
"type": "Microsoft.NotificationHubs/namespaces/notificationHubs/AuthorizationRules",
"apiVersion": "2017-04-01",
"properties": {
"rights": [
"Listen",
"Manage",
"Send"
]
},
"copy": {
"name": "notificationhubsauthroizationrulescopy",
"count": "[length(parameters('notificationhubAuthorizationruleNameSuffix'))]"
},
"dependsOn": [
"notificationhubscopy"
]
}
]
}
Deployment:
AFAIK, to accomplish requirement of getting output (in this case primaryConnectionStrings of multiple notification hubs' authorization rules) from ARM template is currently an unsupported feature. I already see related feature requests / feedback here and here. I would recommend you to up-vote these feature requests / feedback or create a new feature request / feedback explaining your use case and requirement. Azure feature team would consider and work on the feature request / feedback based on the votes, visibility and priority on it.
Azure document references:
ARM template reference for NotificationHubs
Resolve Invalid Template errors
Create multiple instances of a resource using copy and copyIndex
ARM template functions like list (ListKeys)
ARM template structure
Defining order for deploying resources in ARM templates
Hope this helps!! Cheers!!
You can't use a copy loop in outputs today - listing the keys is fine, but you have to know how many you need at design time and hardcode each output. We're working on a fix for that but not there yet.
You could emulate this by using your second option - deploying in a nested deployment and outputting each key in it's own deployment, but then you have to iterate through all the deployments to get all the outputs.

How to authenticate an Azure EventGrid API Connection using a script?

I am creating an EventGrid API Connection using an ARM Template. It gets created successfully, however, i still have to authenticate it by hand via Azure Portal.
Here is my ARM Template:
"resources": [
{
"type": "Microsoft.Web/connections",
"apiVersion": "2016-06-01",
"name": "[parameters('azureEventGridConnectionAPIName')]",
"location": "[resourceGroup().location]",
"properties": {
"api": {
"id": "[concat(subscription().id, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/', 'azureeventgrid')]"
},
"displayName": "[parameters('azureEventGridConnectionAPIName')]"
},
"dependsOn": []
}
]
Am i missing something in the template that is responsible for authenticating the Connection right away?
Is there a way to authenticate that connection using for example Azure PowerShell so i can automate that process?
Am i missing something in the template that is responsible for authenticating the Connection right away?
Yes, we could create a service principal authentication during deploy. Following is the demo code.
"resources": [
{
"type": "Microsoft.Web/connections",
"apiVersion": "2016-06-01",
"name": "[parameters('azureEventGridConnectionAPIName')]",
"location": "[resourceGroup().location]",
"properties": {
"api": {
"id": "[concat('/subscriptions/subscriptionId', '/providers/Microsoft.Web/locations/', 'eastasia', '/managedApis/', 'azureeventgrid')]"
},
"parameterValues": {
"token:clientId": "[parameters('clientId')]",
"token:clientSecret": "[parameters('clientSecret')]",
"token:TenantId": "[parameters('TenantId')]",
"token:grantType": "[parameters('grantType')]"
},
"displayName": "[parameters('azureEventGridConnectionAPIName')]"
},
"dependsOn": []
}
]
Parameters.json
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"azureEventGridConnectionAPIName": {
"value": "azureEventGridConnectionAPIName"
},
"clientId": {
"value": "clientId"
},
"clientSecret": {
"value": "secret key"
},
"TenantId": {
"value": "tenant id"
},
"grantType": {
"value": "client_credentials"
}
}
}

Tags Not Being Deployed to Server Farm with Azure ARM template

EDIT 11/15/2016: This was a bug in Azure which was fixed a couple of days ago.
Original post:
I'm trying to create several app services which depend on a server farm. I'm using an ARM template to deploy it. I'm using the same tags and tag format on every other resource in the template and they are getting created, but for some reason the tags on the server farm aren't. I can create the tags on the server farm through the Azure Portal and the Resource Explorer, but not through the ARM template.
Here's part of my resources section:
{
"comments": "",
"type": "Microsoft.Web/serverfarms",
"sku": {
"name": "S3",
"tier": "Standard",
"size": "S3",
"family": "S",
"capacity": 1
},
"tags": {
"tag1": "[parameters('tag1Value')]",
"tag2": "[parameters('tag2Value')]",
"tag3": "[parameters('tag3Value')]",
"tag4": "[parameters('tag4Value')]",
"tag5": "[parameters('tag4Value')]",
"tag6": "[parameters('tag6Value')]",
"tag7": "[parameters('tag7Value')]"
},
"name": "[variables('serverFarmName')]",
"apiVersion": "2015-08-01",
"location": "[parameters('location')]",
"properties": {
"name": "[variables('serverFarmName')]",
"numberOfWorkers": 1
},
"dependsOn": []
},
[...]
Any known issues with this? Do I have the tags in the wrong place?
Edit 8/8/2016:
Deploying just a server farm works correctly, but as soon as I add a site to that server farm the tags aren't deployed correctly. Here's what happens: Deployment starts, the server farm is created. Before the site is created I can rush into the Azure portal and see the tags created correctly on the server farm. As soon as the site is created I refresh, go back into the server farm, and the tags have disappeared.
It works fine on my side, you can try to leverage the Azure Resource Group project in Visual studio as mentioned at https://blogs.msdn.microsoft.com/kaevans/2015/11/22/creating-arm-templates-with-azure-resource-explorer/.
Here is my simple test template for your information:
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"tag1Value": { "type": "string" },
"tag2Value": { "type": "string" },
"tag3Value": { "type": "string" },
"tag4Value": { "type": "string" },
"tag5Value": { "type": "string" },
"tag6Value": { "type": "string" },
"tag7Value": { "type": "string" },
"garysfName": {
"type": "string",
"minLength": 1
},
"garysfSKU": {
"type": "string",
"allowedValues": [
"Free",
"Shared",
"Basic",
"Standard"
],
"defaultValue": "Free"
},
"garysfWorkerSize": {
"type": "string",
"allowedValues": [
"0",
"1",
"2"
],
"defaultValue": "0"
}
},
"variables": {
},
"resources": [
{
"name": "[parameters('garysfName')]",
"type": "Microsoft.Web/serverfarms",
"location": "[resourceGroup().location]",
"apiVersion": "2014-06-01",
"dependsOn": [ ],
"tags": {
"displayName": "garysf",
"tag1": "[parameters('tag1Value')]",
"tag2": "[parameters('tag2Value')]",
"tag3": "[parameters('tag3Value')]",
"tag4": "[parameters('tag4Value')]",
"tag5": "[parameters('tag4Value')]",
"tag6": "[parameters('tag6Value')]",
"tag7": "[parameters('tag7Value')]"
},
"properties": {
"name": "[parameters('garysfName')]",
"sku": "[parameters('garysfSKU')]",
"workerSize": "[parameters('garysfWorkerSize')]",
"numberOfWorkers": 1
}
},
{
"name": "[variables('garyarmwebappName')]",
"type": "Microsoft.Web/sites",
"location": "[resourceGroup().location]",
"apiVersion": "2015-08-01",
"dependsOn": [
"[concat('Microsoft.Web/serverfarms/', parameters('garysfName'))]"
],
"tags": {
"[concat('hidden-related:', resourceGroup().id, '/providers/Microsoft.Web/serverfarms/', parameters('garysfName'))]": "Resource",
"displayName": "garyarmwebapp"
},
"properties": {
"name": "[variables('garyarmwebappName')]",
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms/', parameters('garysfName'))]"
}
}
],
"outputs": {
}
}
And the parameters JSON file:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"tag1Value": { "value": "tag11" },
"tag2Value": { "value": "tag22" },
"tag3Value": { "value": "tag33" },
"tag4Value": { "value": "tag44" },
"tag5Value": { "value": "tag55" },
"tag6Value": { "value": "tag66" },
"tag7Value": { "value": "tag77" },
"garysfName": {
"value": "garyserverfarms"
}
}
}
And you can refer to https://ms.portal.azure.com/?flight=1&flight.browsegrid2=true&flight.pov2=true&flight.resourcemenuperf=true#blade/HubsExtension/SubscriptionTagsListBlade to check the tag list on Azure portal.

Resources