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 listor using the Azure Portal.
-
Create a service principal with the
Readerrole and scope it to the subscription you want to work with. You can use which everRoleyou wish. I just usedReaderas 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 IDpassword==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.

