0

I have a storage account and I want to give permission to one of my App Service in "Storage Account Key Operator Service Role". Similar to the below action in Azure portal.

Azure Portal Add Permission

himanshu219
  • 654
  • 7
  • 22
  • It seems there is no Python SDK to do that, is it possible for you to use rest api, powershell or azure cli? – Joy Wang Oct 12 '18 at 05:20
  • @JoyWang I looked into this https://github.com/Azure/azure-sdk-for-python but haven't found any api for that.Any good workarounds are also welcome. – himanshu219 Oct 12 '18 at 06:11

2 Answers2

1

Any good workarounds are also welcome.

Here are some workarounds for you.

1.Use powershell, refer to this link.

New-AzureRmRoleAssignment -ObjectId <ObjectId> -RoleDefinitionName "Storage Account Key Operator Service Role" -Scope "<your storage account resourceID>"

2.Use Azure CLI, refer to this link.

az role assignment create --role "Storage Account Key Operator Service Role" --assignee-object-id "<object-id>" --scope "<your storage account resourceID>"

3.Use Rest API, refer to this link.

PUT https://management.azure.com/{scope}/providers/Microsoft.Authorization/roleAssignments/{roleAssignmentName}?api-version=2015-07-01

4.Use ARM template, refer to this link.

Joy Wang
  • 39,905
  • 3
  • 30
  • 54
  • How to get the objectId of the resource which I want to authorize? – himanshu219 Oct 16 '18 at 13:08
  • @himanshu219 If you enable the MSI of the web app, it will generate a service principal, just go to Enterprise Application in Azure Active Directory,search it with the name of your web app, the objectid is the objectid of the service principal. – Joy Wang Oct 16 '18 at 15:38
  • @himanshu219 Could you find it? If not, I can give you more details. – Joy Wang Oct 17 '18 at 02:41
  • yes. Thanks for the help, though I got it but I am looking into a way to get the object id programmatically. – himanshu219 Oct 17 '18 at 02:43
  • @himanshu219 Of course you can, just use this command `(Get-AzureRmADServicePrincipal -DisplayName ).Id`, the result is the objectid. – Joy Wang Oct 17 '18 at 02:49
  • @himanshu219 Could it solve your issue? Or you want to get it with other language? – Joy Wang Oct 17 '18 at 03:05
  • yes i am using azure's graphrbac python module which gives list of service principals and now it is throwing permission denied error and I think I have to be admin. I'll give a try and let you know. Thanks for the help. – himanshu219 Oct 17 '18 at 03:09
0

After spending so much time I was able to use python for authorizing app service.Here's the approach I followed

The credentials you are using should belong to subscription owner because contributor is not allowed to make access changes.

Here's the python packages that one needs to install

azure-mgmt-authorization==0.50.0
azure-graphrbac==0.51.0

Here's the code snippet

subscription_id = config['SUBSCRIPTION_ID']
credentials = ServicePrincipalCredentials(
    client_id=config['AZURE_CLIENT_ID'],
    secret=config['AZURE_CLIENT_SECRET'],
    tenant=config['AZURE_TENANT_ID']
)
graph_credentials = ServicePrincipalCredentials(
    client_id=config['AZURE_CLIENT_ID'],
    secret=config['AZURE_CLIENT_SECRET'],
    tenant=config['AZURE_TENANT_ID'],
    resource="https://graph.windows.net"
)


def get_object_id(full_app_name, resource_name_prefix, resource_type="Microsoft.Web/sites"):

    gcli = GraphRbacManagementClient(graph_credentials, config['AZURE_TENANT_ID'])
    sp = gcli.service_principals.list(filter="displayName eq '%s'" % full_app_name)
    sp = next(sp, False)
    if sp:
        print("Found Service Principal %s" % sp.display_name)
        return sp.object_id
    else:
        raise Exception("Service Principal not found")


def delete_keylistrole_appservice(resource_group_name, storage_name, role_assignment_name):

    resource_provider = "Microsoft.Storage"
    resource_type = "storageAccounts"
    scope = '/subscriptions/%s/resourceGroups/%s/providers/%s/%s/%s' % (
        subscription_id, resource_group_name, resource_provider, resource_type, storage_name)
    auth_cli = AuthorizationManagementClient(credentials, subscription_id, api_version="2015-07-01")
    resp = auth_cli.role_assignments.delete(scope, role_assignment_name)
    print("%s App Service access revoked %s Storage account" % (role_assignment_name, storage_name))


def assign_keylistrole_appservice(resource_group_name, storage_name, app_service_name):

    resource_provider = "Microsoft.Storage"
    resource_type = "storageAccounts"
    scope = '/subscriptions/%s/resourceGroups/%s/providers/%s/%s/%s' % (
        subscription_id, resource_group_name, resource_provider, resource_type, storage_name)
    role_assignment_name = str(uuid.uuid4())

    role_id = "/subscriptions/%s/providers/Microsoft.Authorization/roleDefinitions/%s" % (subscription_id, "81a9662b-bebf-436f-a333-f67b29880f12")
    principal_id = get_object_id(app_service_name)
    props = RoleAssignmentProperties(role_definition_id=role_id, principal_id=principal_id)

    auth_cli = AuthorizationManagementClient(credentials, subscription_id, api_version="2015-07-01")
    resp = auth_cli.role_assignments.create(scope, role_assignment_name, properties=props)
    print("%s App Service authorized to access %s Storage account" % (app_service_name, storage_name))
    return role_assignment_name

Note the graph_credentials they are different than credentials as they require resource="https://graph.windows.net"

himanshu219
  • 654
  • 7
  • 22