Serviceprincipal template for Azure Datalake analytics in datafactory - azure

on this page:
https://learn.microsoft.com/en-us/azure/data-factory/v1/data-factory-usql-activity
there is a template for using Azure Datalake analytics in azure datafactory with service principal (instead of authorizing manually for each use).
the template looks like this:
{
"name": "AzureDataLakeAnalyticsLinkedService",
"properties": {
"type": "AzureDataLakeAnalytics",
"typeProperties": {
"accountName": "adftestaccount",
"dataLakeAnalyticsUri": "azuredatalakeanalytics.net",
"servicePrincipalId": "<service principal id>",
"servicePrincipalKey": "<service principal key>",
"tenant": "<tenant info, e.g. microsoft.onmicrosoft.com>",
"subscriptionId": "<optional, subscription id of ADLA>",
"resourceGroupName": "<optional, resource group name of ADLA>"
}
}
}
This template does not work in azure data factory, it insists that for the type
"AzureDataLakeAnalytics", it is not possible to have "serviceprincipalid" and it still requires "authorization" as a property.
my question is:
what is the correct json template for configuring a AzureDataLakeAnalyticsLinkedService with a serviceprincipal ?

Ok, sorry for asking a question that i figured out myself in the end.
While it is true that the azure portal complains about the template it does allow you deploy it. I had of course tried this, but since the azure portal does not show the error message, only an error flag, i did not realize the error was from the service principals lack of permission and not from the template it complained about.
So by adding more permissions to the service principal and deploying the json, disregarding the compiler complaints. It did work. Sorry for bothering.

Related

How to test within Azure - Azure Resource Manager (ARM Templates)

Assume we have a Checkpoint Firewall Template created on Azure Portal. Is there a way to test the Template within Azure? Also if the Template is modified, is there a way to Test that new modified Template within Azure?
You can test an ARM Template by using it in a deployment. You can also use the what-if setting to produce hypothetical output without actually deploying anything.
Microsoft Azure Docs for What-If
To create a What-If deployment you can proceed a number of ways; Azure CLI, PowerShell, REST, etc. Here is an example using REST (Postman).
Use the endpoint
POST https://management.azure.com/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/{deploymentName}/whatIf?api-version=2020-06-01
Provide a body payload:
{
"location": "westus2",
"properties": {
"mode": "Incremental",
"parameters": {},
"template": {}
}
}
Add your template and parameters. Supply a bearer token for authentication and deploy.
You can check the Azure What-If REST API docs here.

How to Create Web Site ARM Template with Managed Identity?

I am attempting to create Azure Resource Manager templates for several web sites that read secrets from a key vault. In reading How to use managed identities for App Service and Azure Functions, the documentation states that the web site ARM template should contain the following upon creation for authenticating with a key vault:
"identity": {
"type": "SystemAssigned"
}
Once the web site is created, the the identity section changes to the following:
"identity": {
"type": "SystemAssigned",
"tenantId": "<TENANTID>",
"principalId": "<PRINCIPALID>"
}
Does this mean that after running the ARM templates to create the web sites that I have to go back into the ARM template(s) and update the identity section for every site so that I can run the ARM templates to update the sites if need be?
no, you dont have to do that. that is expected. it will not delete that. just rerun it and nothing will change.

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.

ARM Template: Looking up a user object Id

I'm trying to programatically insert the object Id of a certain user account into an ARM template, like this:
"objectId": "[reference(resourceId('Microsoft.AAD/domainServices/user/read','domain','User.Name'),'2019-01-01').Id]",
I've tried many different resource providers in an attempt to get this to work. For example:
"objectId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities/read','user#domain.onmicrosoft.com'),'2019-01-01').Id]",
and:
"objectId": "[reference(resourceId('Microsoft.Portal/usersettings/read','user#domain.onmicrosoft.com'),'2018-10-01').Id]"
I looked up the API call used to get a list of users, to see if that would hint at the correct provider to use (it didn't):
GET https://graph.windows.net/{TenantId}/users?api-version=1.6 HTTP/1.1
I've been looking through this list of provider operations but have found two problems with this:
1 I can't see an operation which looks relevant to what I want to do.
2 It doesn't provide information on what parameters are required.
So I guess I have two questions really:
How do I dynamically look up the ObjectId of a user in an ARM template?
How do I find out in future which lookup functions are available and which parameters are required?
You could not insert the user object Id in the ARM template.
The user account is managed by your Azure AD tenant, it is not the azure resource, the ARM template is for the azure resources in your subscription.
Reference:https://learn.microsoft.com/en-us/azure/azure-resource-manager/resource-group-overview
Azure Resource Manager is the deployment and management service for Azure. It provides a consistent management layer that enables you to create, update, and delete resources in your Azure subscription.
You can try from below code if you have VM in same template and enabled managed identity
https://learn.microsoft.com/en-us/azure/azure-resource-manager/resource-group-template-functions-resource#remarks-1
{
"type": "Microsoft.KeyVault/vaults",
"properties": {
"tenantId": "[reference(concat('Microsoft.Compute/virtualMachines/', variables('vmName')), '2017-03-30', 'Full').identity.tenantId]",
"accessPolicies": [
{
"tenantId": "[reference(concat('Microsoft.Compute/virtualMachines/', variables('vmName')), '2017-03-30', 'Full').identity.tenantId]",
"objectId": "[reference(concat('Microsoft.Compute/virtualMachines/', variables('vmName')), '2017-03-30', 'Full').identity.principalId]",
"permissions": {
"keys": [
"all"
],
"secrets": [
"all"
]
}
}
]
I find the best way to achieve this is to expose the ID as a parameter, then when you call the ARM template deployment, simply pass the parameter into the template.
How do you get the ID into the template parameter? Well, I run my ARM deployments via Azure DevOps CI/CD and I use the pipeline task AzureAppConfiguration.azure-app-configuration-task.custom-build-release-task.AzureAppConfiguration#1 to extract the ID from my own custom configuration setup.
How do you get the ID into the Azure App Configuration service? Well, when I seed an environment for the first time there will be some initial setup, e.g. users and groups. I just then run some scripts to extract this kind of "metadata" into my Azure App Configuration service.
e.g.
APP_ID=$(az ad sp list --all --query "[?displayName=='name-of-spn'].appId" --output tsv)
az appconfig kv set --name name-of-app-config-store --key name-of-spn-app-id --value ${APP_ID}
I think I have solution.
I am tying to refer to a Client ID in a Managed User Identity generated by an ARM template.
I have declared the name of the Managed Identity as a Parameter to use as an administrator for an SQL server:
[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities',parameters('managed-identity')), '2018-11-30', 'full').properties.clientId]
Once you switch our the parameter you should be good to go.

System group membership cannot be changed

I have generated template from existing Azure API management resource, modified it a bit, and tried to deploy using Azure CLI. But I'm getting the following error:
Deployment failed. Correlation ID: 7561a68f-54d1-4370-bf6a-175fd93a4b99. {
"error": {
"code": "MethodNotAllowed",
"message": "System group membership cannot be changed",
"details": null
}
}
But all the APIs are getting created and working fine. Can anyone help me solve the error. This is the command I tried to deploy in my ubuntu machine:
az group deployment create -g XXXX --template-file azuredeploy.json --parameters #param.json
Service Group Template:
{
"type": "Microsoft.ApiManagement/service/groups",
"apiVersion": "2018-06-01-preview",
"name": "[concat(parameters('service_name'), '/administrators')]",
"dependsOn": [
"[resourceId('Microsoft.ApiManagement/service', parameters('service_name'))]"
],
"properties": {
"displayName": "Administrators",
"description": "Administrators is a built-in group. Its membership is managed by the system. Microsoft Azure subscription administrators fall into this group.",
"type": "system"
}
}
You have several options if you want to copy an API Management instance to a new instance. Using the template is not listed here.
Use the backup and restore function in API Management. For more information, see How to implement disaster recovery by using service backup and restore in Azure API Management.
Create your own backup and restore feature by using the API Management REST API. Use the REST API to save and restore the entities from the service instance that you want.
Download the service configuration by using Git, and then upload it to a new instance. For more information, see How to save and configure your API Management service configuration by using Git.
Update:
I have Confirmed with Microsoft engineer that ARM template deployment for APIM failed is an known issue and is planning to fix it.(5/7/2019)

Resources