Logic apps in a multi tenant environment - azure

We are planning to build a SFTP connector using logic apps which will basically take a file uploaded to azure blob and upload it to a sftp location.
We are SaaS product and are dealing with multiple customers. Also we have storage accounts per customer or tenant.
My questions is how would this logic app should be Deployed
1. should it be a single logic app which can listen to multiple storage accounts and upload the files .Right now I cant figure out how this can be done.
2. Should it be a logic app / tenant configured one to one with the storage account of the tenant
I would like to know what is the usual pattern followed in a multi-tenant environment and are their any pros / cons of deploying a logic app / tenant.

You don't need to create one Logic App per tenant. What you could do is to create an API connection per storage account (per tenant). You could do it with ARM Templates and Azure CLI. You could give the API connection an Id based on your tenantId
Then, in your Logic App workflow you can chose at run time the API connection dynamically, depending on the tenant Id.
e.g.
"Get_blob_content": {
"inputs": {
"host": {
"connection": {
"name": "/subscriptions/<id>/resourceGroups/<id>/providers/Microsoft.Web/connections/#{variables('tenantId')}"
}
},
"method": "get",
"path": "/datasets/default/files/.../content",
"queries": {
"inferContentType": true
}
},
"metadata": {
"...": "..."
},
"runAfter": {},
"type": "ApiConnection"
}
It would be up to you to decide how to name the API Connection, how to get it at runtime, and how to get the full connectionId at runtime. But hopefully you get the idea of what you can do the code above.
HTH

Related

Azure logic app - How can I share integration account across multiple resource groups

I am trying to deploy my logic app to multiple environments using CI/CD pipeline. I am getting an error -The client 'guid' with object id ''guid' ' has permission to perform action 'Microsoft.Logic/workflows/write' on scope 'Test Resource group'; however, it does not have permission to perform action 'Microsoft.Logic/integrationAccounts/join/action' on the linked scope(s) 'Development Resource group integration account' or the linked scope(s) are invalid.
Creating another integration account for test resource group doesnt come under free tier. Is there a way to share integration account across multiple resource groups
Not sure what the permissions issue is but you might need to give more information around this.
But try the below first in your pipeline. Works for us with 3 different resource groups and two integration accounts
"parameters": {
"IntegrationAccountName": {
"type": "string",
"minLength": 1,
"defaultValue": "inter-account-name"
},
"Environment": {
"type": "string",
"minLength": 1,
"defaultValue": "dev"
}
},
"variables": {
"resourceGroupName": "[if(equals(parameters('Environment'), 'prd'),'rg-resources-production','rg-resources-staging')]",
"LogicAppIntegrationAccount": "[concat('/subscriptions/3fxxx4de-xxxx-xxxx-xxxx-88ccxxxfbab4/resourceGroups/',variables('resourceGroupName'),'/providers/Microsoft.Logic/integrationAccounts/',parameters('IntegrationAccount'))]",
},
In the above sample, we had two different integration accounts one for testing and one for production. This is why I have set the integration account name as a parameter as it changes between environments.
I have created a variable "resourceGroupName" this is important because this url is setting up a direct link to the integration account which is stored in a known resource group. In this sample I have included an if statement using the value set at the "environment" parameter. This helps select which resource group is going to be used.
I then create another variable which stores the new URL. Replace the subscription guid with your own: 3fxxx4de-xxxx-xxxx-xxxx-88ccxxxfbab4.
Once that is created you need to change the ARM template to use the variable you just created. To set it,place in the properties object.
"properties": {
"state": "Enabled",
"integrationAccount": {
"id": "[variables('LogicAppIntegrationAccount')]"
},
So for you pipeline it should just be a normal arm template but with these two parameters above being set.
Let me know if you have more questions around this.

How to read and update secrets information in parameters.json file of Azure Logic App from Azure Key Vault

I have Azure Logic App that processes messages from Service Bus session-based queue using When one or more messages arrive in a queue (peek-lock) connector and then inserting into SQL Database.
Note: In Azure Logic App, this is When one or more messages arrive in a queue (peek-lock) first trigger.
I want to protect the connection strings of Azure Service Bus and Azure SQL Database. For that I used Azure Key Vault to store connection strings information of Azure Service Bus and Azure SQL Database.
I have followed this documentation to read secrets from Azure Key Vault.
But I want to use the secrets information in parameters.json file. Because currently I have hardcoded the connection strings of Azure Service Bus and Azure SQL Database in parameters.json file.
So, can anyone suggest me ead and update secrets information in parameters.json file of Azure Logic App from Azure Key Vault.
Azure Resource Manager Templates allow for integration of parameters with KeyVault to pull secrets from it.
https://learn.microsoft.com/en-us/azure/azure-resource-manager/templates/key-vault-parameter?tabs=azure-cli
Which should look like this
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"adminLogin": {
"value": "exampleadmin"
},
"adminPassword": {
"reference": {
"keyVault": {
"id": "/subscriptions/<subscription-id>/resourceGroups/<rg-name>/providers/Microsoft.KeyVault/vaults/<vault-name>"
},
"secretName": "ExamplePassword"
}
},
"sqlServerName": {
"value": "<your-server-name>"
}
}
}
Remember to add Logic Apps secret obfuscation
https://learn.microsoft.com/en-us/azure/logic-apps/logic-apps-securing-a-logic-app#secure-data-in-run-history-by-using-obfuscation

How retrieve the storage account connection string from seperate resource group

I have two resource group running in one subscription and inside the subscription I have two resource group for example: RG1 and RG2. RG1 contains a storage account whereas RG2 contains a web app.I have used an arm template to create the resources. Inside the app-settings in the RG2 web app,I have to manually pass the storage accounts' connection string from RG1. Is there any way to fetch the connection string dynamically using arm script,in this case?
Have you looked at using MSI authentication for your Web App. If you are deploying ARM add this to the Web App
"identity": {
"type": "SystemAssigned"
},
This will create a Managed Service Identity which will eliminage the need to even managed the connection string.
After the App has an MSI then in the Storage account grant the MSI an RBAC role to the storage account by looking up the associated Role ID
and configuring your ARM template to include the RBAC assignment.
Personally I tend to store my roles as json objects variables since the IDs are the same across all subscriptions. It makes them easier to assign to specific object or MSI IDs.
"Contributor": {
"RoleID": "[concat(variables('roleDefinition'), 'b24988ac-6180-42a0-ab88 20f7382dd24c')]",
"RoleName": "Contributor"
},
That way when doing the assignment it would look like:
{
"type": "Microsoft.Storage/storageAccounts/providers/roleAssignments",
"apiVersion": "2018-09-01-preview",
"name": "[concat(variables('storageName'), '/Microsoft.Authorization/', guid(uniqueString(variables('storageName'),variables('Reader').RoleName,parameters('principalId'))))]",
"dependsOn": [
"[variables('storageName')]"
],
"properties": {
"roleDefinitionId": "[variables('Contributor').RoleID]",
"principalId": "[reference(resourceId('Microsoft.Web/sites', variables('webSiteName')), '2018-02-01', 'Full').identity.principalId]"
}
}
You may need to tweak since the storage account and Web App are in different resource groups but hopefully this gets you started.
If you aren't comfortable with the MSI piece or unable to other options would be to store the secret for the connection in KeyVault and have your Web App call that to get the secret.

Create SubscriptionCloudCredentials for WebSiteManagementClient without Azure AD Application

I'm looking for a simple solution to Authenticate and use the WebSiteManagementClient. The examples I've seen utilize an Azure AD Application to create the SubscriptionCloudCredentials required. I would prefer to create the SubscriptionCloudCredentials without the use of an AD Application.
If at all possible, I would prefer to just use the Web Deploy un/pw credentials found in the Publish Profile Settings XML (as I already have code that uses these to interact with the kudu api with basic auth)
I found this potential solution that instead uses a management certificate (more info). But again, if at all possible, I would prefer to just use the Web Deploy un/pw.
(I understand the management cert is at a subscription level, and the Web Deploy un/pw are at a App Service/WebSite instance level. I'm just stating what my desired solution would look like.)
Management certificates allow you to authenticate only with the classic deployment (Azure Service Management) model and not the Azure Resource Management deployment model.
If your web app is not created using the classic deployment model, you'll need a TokenCloudCredential instead of the CertificateCloudCredential.
Technically, you can still create Certificate-based SubscriptionCloudCredentials but it will only work with Azure web app created with the classic deployment model.
I would prefer to just use the Web Deploy un/pw.
If you want to upload certificate to Azure WebApp during Web Deploy then we can use ARM template , more details please refer to the document.
{
"name": "[parameters('certificateName')]",
"apiVersion": "2014-04-01",
"type": "Microsoft.Web/certificates",
"location": "[resourceGroup().location]",
"properties": {
"pfxBlob": "pfx base64 blob",
"password": "some pass"
}
}
About how to create subscriptionCloudCredentials with certificate and how to create customized cert, I did a demo for it. More details please refer to another SO thread.
If we try to run the project on the Azure. Please refer to document Using Certificates in Azure Websites Applications. Adding an app setting named WEBSITE_LOAD_CERTIFICATES with its value set to the thumbprint of the certificate will make it accessible to your web application
So we also need to add the AppSetting in the ARM template, more detail info please refer to the document.
  
{
"name": "appsettings",
    "type": "config",
    "apiVersion": "2015-08-01",
    "dependsOn": [
        "[concat('Microsoft.Web/sites/', variables('webSiteName'))]"
    ],
    "tags": {
        "displayName": "WebAppSettings"
    },
    "properties": {
        " WEBSITE_LOAD_CERTIFICATES ": "thumbprint "
    }

Create database account on Azure with specific password using ARM templates

I want to run Azure Resource Group Deployment as part of my deployment process. This should create two resources: App Service (asp.net core) and DocumentDB account.
After that I need to store account credentials (account name and password) in App Settings block of my App Service. Normally I could configure App Service to read the password from existing Azure Key Vault.
But if the database account is not created yet, the password is generated automatically and I would need to update it manually.
Is it possible to create the database account specifying the password (reading value from Key Vault)? This way the deployment would be automated whether the database account was created or not.
I don't see where's the problem in this one, just specify the secret in your template:
"parameters": {
"adminPassword": {
"reference": {
"keyVault": {
"id": "/subscriptions/{guid}/resourceGroups/{group-name}/providers/Microsoft.KeyVault/vaults/{vault-name}"
},
"secretName": "sqlAdminPassword"
}
}
}
https://azure.microsoft.com/en-us/documentation/articles/resource-manager-keyvault-parameter/

Resources