Microsoft Azure Auth Error - python

I'm learning Microsoft Azure and using python3. I got following error code :
C:\Python\python.exe D:/Phyton/Restapi/a.py
Cannot find resource group sgelastic. Check connection/authorization.
{
"error": {
"code": "AuthorizationFailed",
"message": "The client '22273c48-3d9d-4f31-9316-210135595353' with object id '22273c48-3d9d-4f31-9316-210135595353' does not have authorization to perform action 'Microsoft.Resources/subscriptions/resourceGroups/read' over scope '/subscriptions/0f3e0eec-****-****-b9f9-************resourceGroups/sgelastic'."
}
}
Process finished with exit code 0
What should ı do? I should create new subscription or something else?
Thank you.

The credentials you are using have not the necessary permissions to read the resource group "sgelastic".
You can add the "contributor" role to these credentials, or a more precise permission to this specific resource group, depending of your needs.
You should read the documentation on RBAC on Azure for that, current is there:
https://learn.microsoft.com/azure/active-directory/role-based-access-control-what-is
The list of available actions (and name of built-in roles that have it) is there:
https://learn.microsoft.com/azure/active-directory/role-based-access-built-in-roles

As #Laurent Mazuel said, try to follow the steps as the figure below to add the necessary permission.
Click the Subscription tab on Azure portal.
Select the subscription of the related resource group.
Move to the Access control (IAM) tab.
Click the + Add button.
Select the role like Contributor in the Add permission dialog.
Search the name of your user or application, and select the one you used in the searched result list.
Save it.
Or you can use Azure CLI 2.0 to create service principal to do it.
az ad sp create-for-rbac --role="Contributor" --scopes="/subscriptions/mySubscriptionID/resourceGroups/myResourceGroupName"
Hope it helps.

Related

Google Ads API - "failed with status "PERMISSION_DENIED" - "User doesn't have permission to access customer."

I am trying to work with Google-ads-API. Running Ubuntu 20.04, Python 3.9(min requirement for the client library to work is 3.6), working with google-ads-api V6. Here's the story of my agony.
I have made a test manager account[A], generated a developer's token, and have "test-level" access to use the API, which is great. Test level allows you to make calls to the API regarding information\reports dealing with test accounts(not production).
Also, went through the whole Oauth2 credentials for account [A], allowed test emails, and after running "examples/authentication/authenticate_in_web_application.py", I am redirected to a webpage, allow my main test manager account to access the second test manager account[B](as instructed by the documentation, to create another test manager account[B], besides the main account[A] with the developer token), a refresh token is generated successfully from this OAuth2 prompt, to allow account [B] to be managed my account [A], added the refresh token to my google-ads.yaml file, and things are all good.
When I run this .py file from the examples
python3 google-ads-python/examples/account_management/list_accessible_customers.py
The result is this:
Total results: 2
Customer resource name: "customers/1792845307"
Customer resource name: "customers/5341438919"
Lovely, took 2 days to get this far. And it's been two days now trying to get past the following.
Please note that the above results are both from my account [B], the API request to get these results was made while the developer token for account [A] is set in the google-ads.yaml file.
So, the .yaml file for now contains Developer account token for account [A], OAuth creds for account[A] on cloud console(.json) file. The refresh token for account [B] that resulted from the Authentication in step1.
Moving on, by running "get_account_information.py", which is also in the examples folder, and passing to it one of the accounts from the above result[mandatory flag --c, which is the client id), I keep getting an access denied error:
python3 get_account_information.py --c 5341438919
I get this:
Request with ID "LhKeU9ZI4zZgnp05VSHbjg" failed with status "PERMISSION_DENIED" and includes the following errors:
Error with message "User doesn't have permission to access customer. Note: If you're accessing a client customer, the manager's customer id must be set in the 'login-customer-id' header. See https://developers.google.com/google-ads/api/docs/concepts/call-structure#cid".```
I have tried setting "the manager's customer id must be set in the 'login-customer-id' ", this login-customer-id is located in the .yaml file. I have tried setting that to both the results from the call in step 2. I also tried adding the account manager ID from account[A]. I tried manually adding account [A] as an account manager for account [B] from withing google-ads's UI, then tried setting the "login-customer-id" again for all these accounts these linking processes, yet, failed miserably.
I am facing this access denied for all the .py files in the example directory. Tried to be as thorough and verbose as possible for this lengthy process, hoping it'll make sense. If you have tried to work with this API, you will understand what I mean, and I look forward to any insight\help\input regarding this, even if you haven't worked with this API.
In the documentation, the guide says that after creating a test developer manager account, all accounts below that will be also test accounts, and will be designated by a red label saying "TEST", otherwise it's a production account. Both accounts [A]+[B] above are test manager\developer accounts, yet don't have any red labels stating they are tests, neither any children I tried creating under them. So I wonder if the error\roadblock I am facing is due to them not being designated as test accounts? But why are they being listed as "Accessible accounts" in Step2.
Thanks a lot! If any other pieces of info should be required, I shall provide.
--------------SOLVED--------------
An update, just a few hours later. I made another new manager account, using the same email used in manager account[B] mentioned in the question. Followed the same steps as mentioned above, but this time after creation, I got this "RED TEST ACCOUNT FLAG".
I run this in terminal, for the 678th time after roughly a hundred previous attempts:
u#ROOT:~/google-ads-python$ python examples/account_management/list_accessible_customers.py
[2021-01-12 11:30:08 - INFO] Request made: ClientCustomerId: None, Host: googleads.googleapis.com:443, Method: /google.ads.googleads.v6.services.CustomerService/ListAccessibleCustomers, RequestId: XIkvfX4b-xxNql705r_jbQ, IsFault: False, FaultMessage: None
Total results: 3
Customer resource name: "customers/1792845307"
Customer resource name: "customers/5341438919"
Customer resource name: "customers/3740041699"
So, the new account which is actually recognized as a test is "3740041699". Take note of this number, it'su sed in the google-ads.yaml file. Added it under "login_customer_id: " there, because it's a "manager account"[B], that manages a child account I made under it. with the number of 991738295.
My .YAML looks like this
# OAuth2 configuration
###############################################################################
# The below configuration parameters are used to authenticate using the #
# recommended OAuth2 flow. For more information on authenticating with OAuth2 #
# see: https://developers.google.com/google-ads/api/docs/oauth/overview #
###############################################################################
developer_token: ******** #[ from Account A]
client_id: ******.apps.googleusercontent.com #[From account A's email, that was used in google cloud console for API OAuth2]
login_customer_id: 3740041699 [The manager test account B, mentioned above]
client_secret: ******** #[From account A's email, that was used in google cloud console for API OAuth2]
refresh_token: 1//********* [After authenticating account A to have access to account B]
Now when running the cherry on top, we have this:
u#ROOT:~/examples/basic_operations/get_campaigns.py -c 9917382925 #ID of child of test manager mentioned above, this is the result:
Campaign with ID 12058644642 and name "Website traffic-Search-1" was found.
[2021-01-12 11:36:39 - INFO] Request made: ClientCustomerId: 9917382925, Host: googleads.googleapis.com:443, Method: /google.ads.googleads.v6.services.GoogleAdsService/SearchStream, RequestId: Py4oeSqyYiQpBFIWuRYgEg, IsFault: False, FaultMessage: None
Which is exactly what is there, as demonstrated in this picture:
Finally after 5 days. Now that it's working, an actually start developing. I would appreciate if anybody is using the python client, and finds this useful, to advise to any best practices regarding server and routing or things they learned while developing with this interesting API.
THANKS! Have a great day.

Fetch Azure Managed Identity from within Function

I am using Azure Managed Identity feature for my python Azure Functions App
and would like to be able to fetch currently assigned Client ID from within the Function App itself.
Search through documentation and azure-identity python sources did not give result I would expect.
Maybe I could:
Query Azure Instance Metadata Service myself to get this ID. (not really happy with this option)
Provision it as env variable during ARM deployment stage/ or by hands later on. (seems good and efficient, but not sure what is the best practice here)
UPDATE
Managed o get it working with ARM template and env variable
Deploys FunctionApp with System Identity
Provisions System Identity as env variable of this same FunctionApp
Idea is to use Microsoft.Resources/deployments subtemplate to update Function App configuration with:
{
"name": "AZURE_CLIENT_ID",
"value": "[reference(resourceId('Microsoft.Web/sites', variables('appName')), '2019-08-01', 'full').identity.principalId]"
},
The simplest option is to go to the identity tab for your Functions app, and turn on "System assigned managed identity".
You can then get the access token without having to provide the client_id, since the token request simply picks the system assigned identity if there is one for the Function app.
If you are using "user assigned managed identity", then you need to provide the client_id: either through env or directly in your code.
You may already be aware, but just an additional note: that you also need to make sure you have given access to your managed identity for the resource you are accessing, for example: going to the Azure resource your Function app needs to access and assigning an appropriate role for your managed identity.
your option 1 (query Azure Instance Metadata Service), is only available on VMs.
UPDATE
Since you need the client_id for other purposes, you may also consider reading it from the response to your request for the access token: client_id is one of the parameters in the JSON token returned to you along with the access token, and its value is the client_id of the managed identity you used (in your case, the system-assigned managed identity)
Here is a sample token response to illustrate this:
{
access_token: <...>,
resource: <...>,
token_type: 'Bearer',
client_id: <client_id of the managed identity used to get this token>
}

Trouble updating IAM to allow AWS Glue to the AWS Secrets Manager

I am working on a project that requires that an AWS Glue Python script access the AWS Secrets Manager.
I tried giving Glue permissions to do this via IAM, but I don't see how; I can see the permissions strings showing that Lambda has access but I don't see a way to edit them.
I tried creating a new role that had the right permissions but when I went to attach it seemed to have disappeared ...
My fallback workaround is to grab the secret via a tiny Lambda and xfer it via S3 to Glue ... but this should be doable directly. Any help you can give is very welcome!
You may need to add SecretsManagerReadWrite policy to the IAM Role that is associated with the AWS Glue. Please check, we are using secrets manager in our AWS Glue.
After adding the policy to the AWS Glue associated IAM Role, please add the following code snippet to read the credentials from the secret manager:
# Getting DB credentials from Secrets Manager
client = boto3.client("secretsmanager", region_name="us-west-2")
get_secret_value_response = client.get_secret_value(
SecretId="mysecrets-info" <--name as configured in secrets manager
)
secret = get_secret_value_response['SecretString']
secret = json.loads(secret)
uname = secret.get('username')
pwd = secret.get('password')
url = secret.get('host')
By the way you need to be an AWS admin user, to modify the IAM role. If you are a power user, please reach out the admin team for adding the policy to the IAM.
The SecretsManagerReadWrite policy does not give permissions only to Lambda. I think you may be looking at the second statement which grants the Role permissions to create Lambdas (used to create Lambdas to rotate secrets).
Looking at the Glue blog post for setting up ETL jobs, they also say you should only need to add the SecretsManagerReadWrite policy to the Glue role. However, they also say that this is just for testing and you should use a policy that grants only the necessary permissions needed (e.g. use an inline policy that grants secretsmanager:GetSecretValue with Resource being the secret in question).
You don't actually say what error message you are seeing. That might be helpful in figuring out what is going wrong.

KustoServiceError when using application authentication

I am having trouble trying to set up a connector to Kusto using the Kusto client library for Python.
I managed to make it work using the with_aad_device_authentication method, by doing the following:
KCSB = KustoConnectionStringBuilder.with_aad_device_authentication(KUSTO_CLUSTER)
KCSB.authority_id = AAD_TENANT_ID
client = KustoClient(KCSB)
KUSTO_QUERY = "Table | take 10"
RESPONSE = client.execute(KUSTO_DATABASE, KUSTO_QUERY)
which requires me to authenticate by going to a web page and entering a code provided by the library.
However, when I am trying to connect to the database using the with_aad_application_key_authentication method it throws me
KustoServiceError: (KustoServiceError(...), [{'error': {'code': 'Forbidden', 'message': 'Caller is not authorized to perform this action', '#type': 'Kusto.DataNode.Exceptions.UnauthorizedDatabaseAccessException' ...
which I don't understand since I have granted my application with the following permissions: Azure Data Explorer (with Multifactor Autentication) and Azure Data Explorer.
I have been struggling on this for a while and I couldn't come up with a solution. Does anyone have any idea of what could be the problem here?
There are two possible reasons:
1) You did not give the app permission on the database itself. Permissions on the Azure data explorer resource (we call it the 'control plane') using the "access control (IAM)" button allow your app to do management operations on the cluster (such as adding and removing databases), while permissions in the database itself allows doing operations within the database such as creating tables and doing queries (we call it the 'data plane'). Please note that you can also provide permissions to all databases in the cluster by clicking on "permissions" button in the cluster blade.
In order to fix it, click on the database in Azure portal and once you are in the database blade, click on the 'permissions' button and give the app permission (admin, user, viewer etc.). see screenshot below.
2) You did not provide the any of the three required datapoints correctly (appId, appKey and authority id)
Here is the relevant screenshot for adding permission in a specific database:
Adding some more context.
Granting your application delegated permissions to ADX only allows your application to perform user authentication for ADX resources, but it does not grant the application itself any roles on your specific ADX resource.
The answer above guides you how to do that.

Create service principal programmatically in Azure Python API

How can I, using the Azure Python API, create a full set of credentials that can later be used to start and deallocate all VMs in a named resource group, without any other permissions?
I have thoroughly researched the example code and both official and unofficial documentation, but I don't even know where to start...
I know I will need a tenant ID, client ID, client secret and subscription ID. Which of those can I make using an API, and how would I go about assigning roles to allow for starting/deallocating VMs of an existing resource group?
Sample code highly sought after, but will take any hint!
You need the azure-graphrbac package to create a Service Principal:
https://learn.microsoft.com/python/api/overview/azure/activedirectory
The closer to a sample might be this unittest:
https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/graphrbac/azure-graphrbac/tests/test_graphrbac.py
For role and permissions, you need azure-mgmt-authorization:
https://learn.microsoft.com/python/api/overview/azure/authorization
Best sample for this one, is probably the sub-part of this sample:
https://github.com/Azure-Samples/compute-python-msi-vm#role-assignement-to-the-msi-credentials
"msi_identity" is a synonym of "service principal" in your context.
Note that all of this is supported by the CLI v2.0:
https://learn.microsoft.com/cli/azure/ad/sp
https://learn.microsoft.com/cli/azure/role/assignment
It might be interested to test the CLI in --debug mode and sniffing in the code repo at the same time:
https://github.com/Azure/azure-cli
(full disclosure, I work at MS in the Azure SDK for Python team)

Categories