This document details how to create credentials to use when making Azure REST API calls or when using the Azure SDK for Go.
I created this gist because my Golang app was returning empty results and when using the REST API I would see this error message:
{
"error": {
"code": "AuthorizationFailed",
"message": "The client '3c470957-xxxxxx' with object id '3c470957-xxxxxx' does not have authorization to perform action 'Microsoft.Resources/resources/read' over scope '/subscriptions/3dcd5fea-zzzzzz' or the scope is invalid. If access was recently granted, please refresh your credentials."
}
}
If you're logged into the Azure CLI, you should be able to list resources using the command az resource list
. If not, use the command az login
to login. Use the command az account show
to verify that you're logged in, then run az resource list
again.
-
Find the Subscription ID you want to work by running
az account subscription list
or using the Azure Portal. -
Create a service principal with the
Reader
role and scope it to the subscription you want to work with. You can use which everRole
you wish. I just usedReader
as an example.
az ad sp create-for-rbac --name "ReaderRoleForMyApp" --role Reader --scopes "/subscriptions/3dcd5fea-ef32-492a-929xxxxxxxxxx"
Output:
{
"appId": "bddc71dd-xxxxxxxxxxxxxxxxxxxxxxxxxx",
"displayName": "ReaderRoleForMyApp",
"password": "hRgY3108wvQGBJxxxxxxxxxxxxxxxxxx",
"tenant": "057bdeef-df61-4308-9624xxxxxxxxxxx"
}
- Update the SDK or REST API Client to use the service principal credentials.
appId
==Client ID
password
==Client Secret
package main
import (
"context"
"fmt"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/arm"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources"
)
// Set the `AZURE_SDK_GO_LOGGING` environment variable to `all` to see the raw HTTP requests and responses.
// Example: `export AZURE_SDK_GO_LOGGING=all`
func main() {
ctx := context.Background()
tenantId := "057bdeef-df61-4308-9624xxxxxxxxxxx"
clientId := "bddc71dd-xxxxxxxxxxxxxxxxxxxxxxxxxx"
clientSecret := "hRgY3108wvQGBJxxxxxxxxxxxxxxxxxx"
subscriptionId := "3dcd5fea-ef32-492a-929xxxxxxxx"
cred, err := azidentity.NewClientSecretCredential(tenantId, clientId, clientSecret, nil)
if err != nil {
fmt.Printf("Error creating credential: %v\n", err)
}
client2, err := armresources.NewClient(subscriptionId, cred,
&arm.ClientOptions{
ClientOptions: policy.ClientOptions{
Logging: policy.LogOptions{
// include HTTP body for log
IncludeBody: true,
},
},
},
)
if err != nil {
fmt.Printf("Error creating client: %v\n", err)
}
fmt.Println("ITEMS //////////////////////////////////////////////////////////////////////")
pager := client2.NewListPager(nil)
for pager.More() {
page, err := pager.NextPage(ctx)
if err != nil {
fmt.Printf("Error getting next page: %v\n", err)
}
for _, item := range page.Value {
fmt.Println("ITEM ID: ", *item.ID)
fmt.Println(*item.ID)
}
}
}
The example uses Postman and sends 2 requests. The first request responds with an access_token
. The second request uses the access_token
as an Authorization Bearer Token for authenticating and calling the resources endpoint.