Azure course that tries to use Azure Cloud Shell fails with "RequestDisallowedByPolicy" using free account - azure

I was asked by Azure Support to post this question, just to see if anyone had a useful opinion.
I am stepping through MS Azure training courses. I created the usual free account to go through these. I've gone through a few dozen of them, and am now at this one:
https://learn.microsoft.com/en-us/learn/modules/secure-and-isolate-with-nsg-and-service-endpoints/3-exercise-network-security-groups?source=learn
This attempts to use the Azure PowerShell service. I had some trouble getting to the PowerShell page. It appears that if I'm not already logged into the portal, it goes into a semi-infinite loop, trying to get to the shell page, then trying to login, then the shell page, and finally it gives up and says "We couldn't sign you in. Please try again.".
However, I was able to work around this. If in a separate tab, I log into the Azure Portal, and then go back and follow the link to Azure Cloud Shell, it passes the login gate and sends me to the page where I choose Bash or PowerShell. The course specifies using Bash. When I select that, it then asks me to create a Storage object. When I confirm that, it gives me the following error (subscription id elided):
{
"error": {
"code": "RequestDisallowedByPolicy",
"target": "cs733f82532facdx4f04x95b",
"message": "Resource 'cs733f82532facdx4f04x95b' was disallowed by policy. Policy identifiers: '[{\"policyAssignment\":{\"name\":\"Enforce tag on resource\",\"id\":\"/subscriptions/xxxxx/providers/Microsoft.Authorization/policyAssignments/740514d625684aad84ef8ca0\"},\"policyDefinition\":{\"name\":\"Enforce tag on resource\",\"id\":\"/subscriptions/xxxxx/providers/Microsoft.Authorization/policyDefinitions/be3862a6-ca1e-40b0-a024-0c0c7d1e8b3e\"}}]'.",
"additionalInfo": [
{
"type": "PolicyViolation",
"info": {
"policyDefinitionDisplayName": "Enforce tag on resource",
"evaluationDetails": {
"evaluatedExpressions": [
{
"result": "True",
"expressionKind": "Field",
"expression": "tags[Department]",
"path": "tags[Department]",
"targetValue": "false",
"operator": "Exists"
}
]
},
"policyDefinitionId": "/subscriptions/xxxxx/providers/Microsoft.Authorization/policyDefinitions/be3862a6-ca1e-40b0-a024-0c0c7d1e8b3e",
"policyDefinitionName": "be3862a6-ca1e-40b0-a024-0c0c7d1e8b3e",
"policyDefinitionEffect": "deny",
"policyAssignmentId": "/subscriptions/xxxxx/providers/Microsoft.Authorization/policyAssignments/740514d625684aad84ef8ca0",
"policyAssignmentName": "740514d625684aad84ef8ca0",
"policyAssignmentDisplayName": "Enforce tag on resource",
"policyAssignmentScope": "/subscriptions/xxxxx",
"policyAssignmentParameters": {
"tagName": {
"value": "Department"
}
}
}
}
]
}
}
I think the simple conclusion from this is that my free account doesn't have enough rights to do what is needed here. The documentation I've read seems to imply that I have to get additional rights on the account in order to do this. However, I'm just using a free account that I created to go through the Azure training courses. It doesn't really make sense to ask me to do this. I've seen other Azure courses create a temporary sandbox supposedly because they have particular objects pre-created in the sandbox, but I'm also thinking that the sandbox has particular permissions that are not available in the free account. It seems to me that the only reasonable fix for this problem is for that course to be refactored to use a temporary sandbox with the correct permissions.
I'm just looking for any opinions on this, and confirmations that this is what should be done.

It doesn't look like you are creating resource, cloudshell storage, on your free subscription. Except if you added to a Work/Corporate tenant.
From the information you provide, subscription you are trying to use has a policy to enforce tags Department, mean any resource created should have a tag with Department information.

Related

Having trouble understanding Azure's Roles JSON

Its just a concept im having trouble understanding with the wildcard * and what that means, so here we have two roles Owner and contributor.
"Name": "Contributor",
"Id": "b24988ac-6180-42a0-ab88-20f7382dd24c",
"IsCustom": false,
"Description": "Lets you manage everything except access to resources.",
"Actions": ["*"],
"NotActions": [
"Microsoft.Authorization/*/Delete",
"Microsoft.Authorization/*/Write",
"Microsoft.Authorization/elevateAccess/Action'],
"DataActions": [],
"NotDataActions": [],
"AssignableScopes": [],
"/"
Name : Owner
Id : 8e3af657-a8ff-443c-a75c-2fe8c4bcb635
IsCustom : False
Description : Grants full access to manage all resources, including the ability to assign roles in Azure RBAC.
Actions : {*}
NotActions : {}
DataActions : {}
NotDataActions : {}
AssignableScopes : {/}
So my hang up is use of the astrisk, i know * under Owner means everything but with contributor, why is it used under the NotActions permissions? Why is it "Microsoft.Authorization/*/Delete" instead of Microsoft.Authorization/Delete". The permission in question stops the contributor from deleting users. So i know how these roles and permissions work, im just really struggling with the syntax. I have read the documentation on microsoft learn but there is something i clearly dont understand about the *. Does anyone with any knowledge know of a way of explaining this to help clear it up or maybe someone could point me to some better documentation? Any help would be greatly appreciated.
Why is it "Microsoft.Authorization/*/Delete" instead of
Microsoft.Authorization/Delete".
To understand this, please see this link especially Operations format section.
Essentially each operation is specified in {Company}.{ProviderName}/{resourceType}/{action} format.
So when you specify the operation as Microsoft.Authorization/*/Delete, you're essentially allowing delete operation on all the resources under Microsoft.Authorization resource provider.
This format also enables you to specify actions granularly at each resource level under a resource provider.

Azure Machine Learning: What error is this?

I am using a Classic Web Service with a non-default endpoint for a Update Resource activity on the Azure Data Factory. This is the error I get:
Screenshot of Error
I didn't find any info on the web and couldn't figure it out myself. This website shows an example that I used by just filling in my values for mlEndpoint, apiKey and updateRessourceEndpoint:
{
"name": "updatableScoringEndpoint2",
"properties": {
"type": "AzureML",
"typeProperties": {
"mlEndpoint": "https://ussouthcentral.services.azureml.net/workspaces/xxx/services/--scoring experiment--/jobs",
"apiKey": "endpoint2Key",
"updateResourceEndpoint": "https://management.azureml.net/workspaces/xxx/webservices/--scoring experiment--/endpoints/endpoint2"
}
}
}
There is no mention of a token that needs to be passed...
this error is basically saying the apiKey you provided is invalid to perform the update resource operation. Here is some posts for your reference: https://social.msdn.microsoft.com/Forums/azure/en-US/3bb77e37-8860-43c6-bcaa-d6ebd70617b8/retrain-predictive-web-service-programmatically-when-do-not-have-access-to-managementazuremlnet?forum=MachineLearning
Please also be noted that if you modified your linked service in ADF, remember to re-deploy the pipeline as well to reflect your change in time.

How can I get the guids of Graph API permissions programmatically for an Azure AD application?

I am trying to add required permissions to an Azure AD application. I already know how to replicate information from a downloaded manifest through a PATCH REST call, e.g.
"requiredResourceAccess": [
{
"resourceAppId": "00000003-0000-0000-c000-000000000000",
"resourceAccess": [
{
"id": "7b9103a5-4610-446b-9670-80643382c1fa",
"type": "Scope"
},
{
"id": "5df07973-7d5d-46ed-9847-1271055cbd51",
"type": "Scope"
}
]
}
]
As explained by Christer Ljung on his blog http://www.redbaronofazure.com/?page_id=181.
But the mystery remains how I can "convert" human-readable scopes such as Mail.Read to these obscure guids. I have read the following blog of Sahil Malik's at http://blah.winsmarts.com/2015-1-Programmatically_register_native_apps_in_Azure_AD_or_Office_365.aspx that explains how to get a list of available guids for a particular ServicePrincipal. E.g. through an http get to https://graph.windows.net/<tenant-id>/servicePrincipals()?api-version=1.6&$filter=appId%20eq%20'00000002-0000-0ff1-ce00-000000000000'> (Exchange) but when I try to get the list of available scopes of ServicePrincipal 00000003-0000-0000-c000-000000000000 (I believe the one for Graph API) the return value is just empty.
Interestingly, with Fiddler I was able to capture an http post request which contains all the guids when adding the permissions through Azure Portal.
Anyone any clue how I can do this programmatically?
After investigation, I discover a way to get permission guid using azure-cli. Share here in case anyone is finding this:
get all permisson and their GUID of a certain service principal by display-name, app-id or object-id. (Note that display-name is not unique and can maps multiple service principal)
$ az ad sp list --filter "displayName eq 'Microsoft Graph'" --query '[].oauth2Permissions[].{Value:value, Id:id, UserConsentDisplayName:userConsentDisplayName}' -o table
Value Id UserConsentDisplayName
------------------------------------------------------- ------------------------------------ -----------------------------------------------------------------------------------------
ServiceHealth.Read.All 55896846-df78-47a7-aa94-8d3d4442ca7f Read service health
ServiceMessage.Read.All eda39fa6-f8cf-4c3c-a909-432c683e4c9b Read service messages
TermStore.ReadWrite.All 6c37c71d-f50f-4bff-8fd3-8a41da390140 Read and write term store data
TermStore.Read.All 297f747b-0005-475b-8fef-c890f5152b38 Read term store data
TeamMember.ReadWriteNonOwnerRole.All 2104a4db-3a2f-4ea0-9dba-143d457dc666 Add and remove members with non-owner role for all teams
Team.Create 7825d5d6-6049-4ce7-bdf6-3b8d53f4bcd0 Create teams
TeamsAppInstallation.ReadWriteForUser 093f8818-d05f-49b8-95bc-9d2a73e9a43c Manage your installed Teams apps
TeamsAppInstallation.ReadWriteSelfForUser 207e0cb1-3ce7-4922-b991-5a760c346ebc Allow the Teams app to manage itself for you
...
$ az ad sp list --filter "appId eq '00000003-0000-0000-c000-000000000000'" --query '[].oauth2Permissions[].{Value:value, Id:id, UserConsentDisplayName:userConsentDisplayName}' -o table | head
Value Id UserConsentDisplayName
------------------------------------------------------- ------------------------------------ -----------------------------------------------------------------------------------------
ServiceHealth.Read.All 55896846-df78-47a7-aa94-8d3d4442ca7f Read service health
ServiceMessage.Read.All eda39fa6-f8cf-4c3c-a909-432c683e4c9b Read service messages
TermStore.ReadWrite.All 6c37c71d-f50f-4bff-8fd3-8a41da390140 Read and write term store data
TermStore.Read.All 297f747b-0005-475b-8fef-c890f5152b38 Read term store data
TeamMember.ReadWriteNonOwnerRole.All 2104a4db-3a2f-4ea0-9dba-143d457dc666 Add and remove members with non-owner role for all teams
Team.Create 7825d5d6-6049-4ce7-bdf6-3b8d53f4bcd0 Create teams
TeamsAppInstallation.ReadWriteForUser 093f8818-d05f-49b8-95bc-9d2a73e9a43c Manage your installed Teams apps
TeamsAppInstallation.ReadWriteSelfForUser 207e0cb1-3ce7-4922-b991-5a760c346ebc Allow the Teams app to manage itself for you
...
Run the below command to get full information of certain service principal including its oauth2Permissions and servicePrincipalNames, etc.
az ad sp show --id 00000003-0000-0000-c000-000000000000 >microsoft_graph_permission_list.json
# microsoft_graph_permission_list.json
{
...
"appDisplayName": "Microsoft Graph",
"appId": "00000003-0000-0000-c000-000000000000",
"objectId": "b19d498e-6687-4156-869a-2e8a95a9d659",
"servicePrincipalNames": [
"https://dod-graph.microsoft.us",
"https://graph.microsoft.com/",
"https://graph.microsoft.us",
"00000003-0000-0000-c000-000000000000/ags.windows.net",
"00000003-0000-0000-c000-000000000000",
"https://canary.graph.microsoft.com",
"https://graph.microsoft.com",
"https://ags.windows.net"
],
"appRoles": [...],
"oauth2Permissions": [
{
"adminConsentDescription": "Allows the app to read and write the full set of profile properties, reports, and managers of other users in your organization, on behalf of the signed-in user.",
"adminConsentDisplayName": "Read and write all users' full profiles",
"id": "204e0828-b5ca-4ad8-b9f3-f32a958e7cc4",
"isEnabled": true,
"type": "Admin",
"userConsentDescription": "Allows the app to read and write the full set of profile properties, reports, and managers of other users in your organization, on your behalf.",
"userConsentDisplayName": "Read and write all users' full profiles",
"value": "User.ReadWrite.All"
},
{
"adminConsentDescription": "Allows the app to read the full set of profile properties, reports, and managers of other users in your organization, on behalf of the signed-in user.",
"adminConsentDisplayName": "Read all users' full profiles",
"id": "a154be20-db9c-4678-8ab7-66f6cc099a59",
"isEnabled": true,
"type": "Admin",
"userConsentDescription": "Allows the app to read the full set of profile properties, reports, and managers of other users in your organization, on your behalf.",
"userConsentDisplayName": "Read all users' full profiles",
"value": "User.Read.All"
},
...
]
...
}
Few things to say about this topic.
First, it is important to note that all of the OAuth2Permission Scopes are registered on the main Application Object in the developer's tenant. Thus, in general, you would not have access to that information, since it would be in a tenant where you are not a user. So as an external developer, these permission scopes are not discoverable via our APIs.
Second, you are able to see that the Azure Portal has access to this information because it has elevated access to query the OAuth2Permissions for all resources in all tenants. This is how our UX is able to populate all the permissions for all the various external and internal resources that you want to use in your tenant. The portal will first check which service principals are in your tenant (service principals get provisioned most commonly once you consent to use the application), then it will look up the Application Object that corresponds to that service principal, and find all the permission scopes. This behavior will hopefully allow you to only see the resource applications which are relevant to you, rather than populating your screen with all possible resources.
Finally, moving forward we are looking to take a step back from having to statically register permissions that clients require to call resource applications. Instead we will be pushing a new Incremental and Dynamic Consent framework. You will note that here that we are taking a dependency on the scope names, rather than the ObjectID GUIDs of those permissions as we did in the past. But still, I agree with you in general that the discoverability of the scopes that resources expose is very heavily dependent their own public documentation. I imagine in the future there might be an endpoint which exposes all the scopes available on a particular resource, but I know of no such work to do this in the near future.
Let me know if this helps!

Creation of user fails after deletion of user with same signInName

I can successfully create users in an Azure AD B2C tenant through the graph api. I can delete the user as well.
When I try to insert a user with the same signInName again, the request fails with this message:
"odata.error": {
"code": "Request_BadRequest",
"message": {
"lang": "en",
"value": "Another object with the same value for property signInNames already exists."
},
"date": "2016-10-11T15:53:58",
"requestId": "911fcff7-f2f0-4126-aa1e-3c03a757ac0d",
"values": [
{
"item": "PropertyName",
"value": "signInNames"
},
{
"item": "PropertyErrorCode",
"value": "ObjectConflict"
}
]
}
After I wait some minutes (5-20?) I can successfully insert the user with the original signInName.
After successful deletion the user is not visible when I list all users.
Renaming the user before deletion works fine but I can still not create the user with the original signInName.
Is it possible to speed this up?
When you created the service-principal, you also created an application.
use this command to also remove the application:
remove-azurerdadapplication -objectId [key]
I have encountered the same issue in Azure AD.
I Don't think there is anything you can do in your code to speed this up. (Azure AD PMs can answer the question of: what is the real SLA for a delete operation to completely propagate through the system)
I guess all you can do is to consider this error as if the user is actually there when you get this error (Although you can see it in the list).
Not sure about your exact scenario, but this was a really edge case for us.
Another workaround that we were thinking about in our case was: not to delete a user at all and just remove their roles if there is a chance that the user with same ID is needed later on
Because when the user is deleted the ObjectID or UserKey changes and we had references in our system to that ObjectId and that object ID will not exist in Azure AD anymore so we decided to keep the users in most cases unless we really had to delete them.

Azure ARM template - derive Automation Account registration Url and Key at runtime

I'm trying to derive the Registration Key and Url of my Azure Automation DSC account inside the ARM template at runtime. I've tried using the same syntax as you would for a storage account, ie.
listKeys(resourceId('Microsoft.Storage/storageAccounts', 'StorageAccountName'), '2015-05-01-preview').key1)
by doing this:
listKeys(resourceId('Microsoft.Automation/automationAccounts', 'AutomationAccountName'), '2015-05-01-preview').key1)
but no luck (it appears the function simply returns null). This would naturally make provisioning an automation account and and a VM and wiring up the VM to the automation account in the same template easy as pie. Has anyone successfully got something similar to work?
As per this GitHub Ticket, this is still under development.
https://github.com/azureautomation/automation-packs/issues/7
With version 2015-10-31 of the Azure Automation API, the following seems to work.
Getting the registration URL:
reference(resourceId('Microsoft.Automation/automationAccounts/', 'AutomationAccountName'), '2015-10-31').RegistrationUrl
Getting the Primary key:
listKeys(resourceId('Microsoft.Automation/automationAccounts/', 'AutomationAccountName'), '2015-10-31').keys[0].value
Getting the Secondary key:
listKeys(resourceId('Microsoft.Automation/automationAccounts/', 'AutomationAccountName'), '2015-10-31').keys[1].value
For reference, the object returned from the listKeys() template function for an Automation account resource looks like this (can easily be found by adding an output value using listKeys() to the outputs section of an ARM template):
{
"keys": [
{
"KeyName": "Primary",
"Permissions": "Full",
"Value": "VALUE OF PRIMARY KEY"
},
{
"KeyName": "Secondary",
"Permissions": "Full",
"Value": "VALUE OF SECONDARY KEY"
}
]
}

Resources