ARM Template - create SQL Server firewall rule for Web App - azure-resource-manager

I have created SQL Server and Database, Web App, published website and database and get to the log on screen of the website.
When I log in I receive a 500 including the IP address of the web app which currently isn't allowed to access the newly created SQL Server.
I'd very much like to harvest the assigned IP address (suspect it is AZURE internal IP address) to create a firewall rule in the template.
I'm successfully doing things like adding app settings for storage account keys and database connections strings. And these are working nicely.
Very frustrating to not be able to find any reference to the internal IP of the web site. I've tried the object explorer in the azure portal.
Suggestions appreciated!
Andy

If you are using Azure SQL, about how to set Azure Database firewall, please refer to the document.
Very frustrating to not be able to find any reference to the internal IP of the web site?
If want to let Azure service to access Azure SQL database, we just need to set
Allow access to Azure services on. And default value is on.
We also could get the outbound IPs, we can get them from the azure resources(https://resources.azure.com/) then add the outboundIpAddresses to the Azure SQL firewall rule allowed IP list.
Note : For Azure WebApp, the outboundIpAddresses are not static ips, they may be changed when we restart the WebApp or change WebApp service plan.
If we want to add firewall rule via ARM template, we could use the following demo code:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"testfirewallAdminLogin": {
"type": "string",
"minLength": 1
},
"testfirewallAdminLoginPassword": {
"type": "securestring"
}},
"variables": {
"testfirewallName": "[concat('testfirewall', uniqueString(resourceGroup().id))]"},
"resources": [
{
"name": "[variables('testfirewallName')]",
"type": "Microsoft.Sql/servers",
"location": "[resourceGroup().location]",
"apiVersion": "2014-04-01-preview",
"dependsOn": [ ],
"tags": {
"displayName": "testfirewall"
},
"properties": {
"administratorLogin": "[parameters('testfirewallAdminLogin')]",
"administratorLoginPassword": "[parameters('testfirewallAdminLoginPassword')]"
},
"resources": [
{
"name": "AllowAllWindowsAzureIps",
"type": "firewallrules",
"location": "[resourceGroup().location]",
"apiVersion": "2014-04-01-preview",
"dependsOn": [
"[resourceId('Microsoft.Sql/servers', variables('testfirewallName'))]"
],
"properties": {
"startIpAddress": "x.x.x.x",
"endIpAddress": "x.x.x.x"
}
}
]
}],
"outputs": {
}
}

Related

dynamically add a user assigned managed identity to a function app during DevOps Deployment

I am creating ARM templates to deploy an azure function.
I can parameterize most things, but I am unable to parameterize UserAssignedManagedIdentities.
The value for a userAssignedManagedIdentity is not a value in the json ARM template, but is instead an object that contains the reference to the managed identity.
ARM does not allow parameterization in this instance.
I can hard code the reference to the managed identity but this is not ideal when deploying across multiple environments.
Is there a way to dynamically add a user assigned managed identity to a function app during Azure Devops Deployment?
This does not work
This works
Update: Adding more detail.
Below is the section of the template, parameterized, and the error that I get.
"resources": [
{
"type": "Microsoft.Web/sites",
"apiVersion": "2022-03-01",
"name": "[parameters('FunctionAppName')]",
"location": "North Europe",
"kind": "functionapp",
"identity": {
"type": "SystemAssigned, UserAssigned",
"userAssignedIdentities": {
"[concat('/subscriptions/', parameters('SubscriptionID'), '/resourcegroups/', parameters('ResourceGroup'),'/providers/Microsoft.ManagedIdentity/userAssignedIdentities/', parameters('UserAssignedManagedEntityName') ]": {}
}
},
"properties": {
"enabled": true,
"hostNameSslStates": [
{
"name": "[concat(parameters('FunctionAppName'),'.azurewebsites.net')]",
"sslState": "Disabled",
"hostType": "Standard"
},

ARM FunctionApp listkeys retrieve previous custom key

We've got ARM deployment template which is working fine, the only issue there is, as we're creating FunctionApp and adding custom key to it that will be referenced in API Management to connect API with FunctionApp backend. It looks like, even with dependsOn in backend resource in template referencing to FunctionKeys resource, listkeys() still fetches one from before deployment. Has anyone faced this scenario and is there anything in particular I'm missing? Or is dependsOn thinking that the key has been deployed already, and even tho future deployments update the key, backend isn't actually waiting for the completion of FunctionKeys resource deployment?
Template snippets:
backends
{
"type": "Microsoft.ApiManagement/service/backends",
"apiVersion": "2018-01-01",
"name": "[concat(parameters('apiManagementServiceName'), '/', variables('functionName'))]",
"dependsOn": [
"[resourceId('Microsoft.ApiManagement/service', parameters('apiManagementServiceName'))]",
"[resourceId('Microsoft.Web/sites', variables('functionName'))]",
"[resourceId('Microsoft.Web/sites/host/functionKeys', variables('functionName'),'default','apimanagement')]"
],
"properties": {
"url": "[concat('https://', variables('functionName'), '.azurewebsites.net/api')]",
"protocol": "http",
"resourceId": "[concat('https://management.azure.com/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Web/sites/', variables('functionName'))]",
"credentials": {
"header": {
"x-functions-key": [
"[listkeys(concat(variables('functionAppId'), '/host/default/'),'2016-08-01').functionKeys.apimanagement]"
]
}
}
}
}
functionKeys
{
"type": "Microsoft.Web/sites/host/functionKeys",
"apiVersion": "2018-11-01",
"name": "[concat(variables('functionName'), '/default/apimanagement')]",
"dependsOn": [
"[resourceId('Microsoft.Web/sites', variables('functionName'))]"
],
"properties": {
"name": "apimanagement"
}
},
The listKeys call is scheduled too early... In a greenfield scenario the deployment would fail, in brownfield you "get the old key" instead of the new one. It's a "limitation" in the template engine that you can work around. Basically, you need to nest the deployment that uses the listKeys function (i.e. your backend resource). There's a little bit of detail on it here in the Use a Nested Deployment section

Exception in function does not return exceptions on functions in function monitor

The azure function is a .net core class library that will receive the message based on the namespace of the model being sent (in the filter as eventType) as an . All deployments are being done using arm templates, which is where this struggle is originating from. The function and eventgrid are deployed fine, but I don't know what i'm doing wrong with the subscription. If I create the subscription in the portal then the handler receives the message and displays traffic on the monitor. If I create the subscription as below then it appears exactly the same in the portal as the portal created one but nothing shows up in the monitor. Am I missing a resource or connection that still needs to be created? I read about system topics and how they're made implicitly in some instances but can be made explicitly, is that what I'm missing? This would be easier to debug if there was a place to export the template for those subscriptions but I don't see them.
Function handler
[FunctionName("FunctionName")]
public async Task Run([EventGridTrigger]EventGridEvent eventGridEvent)
{
...
}
}
eventgrid creation
{
"type": "Microsoft.EventGrid/topics",
"apiVersion": "2020-06-01",
"name": "[variables('EventGridName')]",
"location": "[resourceGroup().location]"
}
subscription creations
{
"name": "[concat(variables('eventSubscriptions')[copyIndex()].eventGridName, '/Microsoft.EventGrid/', variables('eventSubscriptions')[copyIndex()].name)]",
"type": "Microsoft.EventGrid/topics/providers/eventSubscriptions",
"apiVersion": "2020-01-01-preview",
"location": "[resourceGroup().location]",
"copy": {
"name": "subscriptionCopy",
"count": "[length(variables('eventSubscriptions'))]"
},
"properties": {
"topic": "[concat('/subscriptions/', subscription().subscriptionId,'/resourcegroups/', resourceGroup().name, '/providers/Microsoft.EventGrid/topics/', variables('eventSubscriptions')[copyIndex()].eventGridName)]",
"destination": {
"endpointType": "AzureFunction",
"properties": {
"resourceId": "[concat('/subscriptions/', subscription().subscriptionId,'/resourcegroups/', resourceGroup().name, '/providers/Microsoft.Web/sites/', variables('eventSubscriptions')[copyIndex()].functionApp, '/functions/' , variables('eventSubscriptions')[copyIndex()].functionName)]",
"maxEventsPerBatch": 1,
"preferredBatchSizeInKilobytes": 64
}
},
"filter": {
"includedEventTypes": [
"[variables('eventSubscriptions')[copyIndex()].eventType]"
]
},
"labels": [],
"eventDeliverySchema": "EventGridSchema"
},
"dependsOn": [
]
}

Getting "parent resource not found" during ARM template deployment

I have private DNS zone zone.private which is already deployed in resource group and I'm trying to add A record to it with ARM template below which fails with Status Message: Can not perform requested operation on nested resource. Parent resource 'zone.private' not found. (Code:ParentResourceNotFound)
I'm supposed to be able to refer to refer to resources deployed in the same resource group to deploy nested resources but it fails for whatever reason. I have another zone called zone.domain.com deployed to the same resource group and deploying to that succeeds with no issues.
{
"type": "Microsoft.Network/dnsZones/A",
"apiVersion": "2018-05-01",
"name": "[concat('zone.private', '/', 'webexport-lb')]",
"properties": {
"TTL": 3600,
"ARecords": [
{
"ipv4Address": "1.1.1.1"
}
]
}
},
If you have a private DNS zone, you could use Microsoft.Network/privateDnsZones/A instead of Microsoft.Network/dnsZones/A.
So change it like this:
{
"type": "Microsoft.Network/privateDnsZones/A",
"apiVersion": "2018-09-01",
"name": "[concat('zone.private', '/', 'webexport-lb')]",
"properties": {
"ttl": 3600,
"aRecords": [
{
"ipv4Address": "1.1.1.1"
}
]
}
}

AnotherOperationInProgress when deploying multiple Azure virtual networks and subnets with ARM at once

I want to deploy a virtual network setup with these vnets / subnets
frontend
firewall
appgw
api
jump
cluster
ingress
agents
each of the subnets is included in the "resources": [...] array of the corresponding virtual network and each of the subnets has the vnet as dependency like this:
{
"apiVersion": "2020-04-01",
"type": "subnets",
"location": "[parameters('location')]",
"name": "ingress",
"dependsOn": [
"[parameters('vnetNameCluster')]"
],
"properties": {
"addressPrefix": "[parameters('subnetPrefixIngress')]"
}
}
However when deploying the virtual networks, very often a conflict is raised:
{
"error": {
"code": "AnotherOperationInProgress",
"message": "Another operation on this or dependent resource is in progress. To retrieve status of the operation use uri: https://management.azure.com/subscriptions/xxxxxx/providers/Microsoft.Network/locations/westus/operations/yyyyyyyyyyyyyyy?api-version=2020-04-01.",
"details": []
}
}
What dependency can I add to avoid this conflict?
After some trial and error I avoided the conflict by adding the previous subnet within a virtual network as a dependency - hence the first subnet still only having a dependency on the virtual network:
{
"apiVersion": "2020-04-01",
"type": "subnets",
"location": "[parameters('location')]",
"name": "agents",
"dependsOn": [
"[parameters('vnetNameCluster')]",
"[resourceId('Microsoft.Network/virtualNetworks/subnets',parameters('vnetNameCluster'),'ingress')]"
],

Resources