Azure SDK for Go authentication with a service principal
In this tutorial, you'll use the Azure SDK for Go to authenticate to Azure with an Azure service principal using either a secret or a certificate.
Azure service principals define the access policy and permissions in an Azure AD tenant. Enabling core features such as authentication during sign-on and authorization during resource access. Removing the need to use personal accounts to access Azure resources. The Azure SDK for Go's Azure Identity module provides a convenient way to authenticate with Azure using a service principal using environment variables, a secret, or a certificate
Follow this tutorial to create and authenticate with the Azure SDK for Go using a service principal.
Prerequisites
- Azure subscription: If you don't have an Azure subscription, create a free account before you begin.
- Go installed: Version 1.16 or above
1. Create an Azure resource group
Before you begin, create a new resource group in Azure.
az group create --name go-on-azure --location eastus
Take note of the Id from the output, you'll use it for the scope of the service account.
2. Create an Azure service principal
Use one of the following techniques to create an Azure service principal:
- Option 1: Create an Azure service principal with a secret
- Option 2: Create an Azure service principal with a certificate
To learn more Azure service principals, see Service principal object.
Option 1: Create an Azure service principal with a secret
Run the following commands to create an Azure service principal.
az ad sp create-for-rbac --name `<servicePrincipalName>` --role Contributor --scope <resourceGroupId>
Replace <servicePrincipalName> and <resourceGroupId> with the appropriate values.
Make sure you copy the password value - it can't be retrieved. If you forget the password, reset the service principal credentials.
Option 2: Create an Azure service principal with a certificate
az ad sp create-for-rbac --name <servicePrincipal> --create-cert --role Contributor --scope <resourceGroupId>
Replace <servicePrincipalName> and <resourceGroupId> with the appropriate values.
3. Authenticate to Azure with a service principal
By using the DefaultAzureCredential, you can avoid writing environment-specific code to authenticate to Azure.
Use the DefaultAzureCredential to configure your service principal credentials by defining environment variables.
Choosing one of the following options to configure your service principal credentials:
To learn more about the DefaultAzureCredential, check out Azure authentication with the Azure SDK for Go
Option 1: Authenticate with a secret
Define the following environment variables:
| Variable name | Value |
|---|---|
AZURE_CLIENT_ID |
Application ID of an Azure service principal |
AZURE_TENANT_ID |
ID of the application's Azure AD tenant |
AZURE_CLIENT_SECRET |
Password of the Azure service principal |
export AZURE_TENANT_ID="<active_directory_tenant_id"
export AZURE_CLIENT_ID="<service_principal_appid>"
export AZURE_CLIENT_SECRET="<service_principal_password>"
Option 2: Authenticate with a certificate
| Variable name | Value |
|---|---|
AZURE_CLIENT_ID |
Application ID of an Azure service principal |
AZURE_TENANT_ID |
ID of the application's Azure AD tenant |
AZURE_CLIENT_CERTIFICATE_PATH |
Path to a certificate file including private key (without password protection) |
export AZURE_TENANT_ID="<active_directory_tenant_id"
export AZURE_CLIENT_ID="<service_principal_appid>"
export AZURE_CLIENT_CERTIFICATE_PATH="<azure_client_certificate_path>"
Use DefaultAzureCredential to authenticate ResourceClient
Use the NewDefaultAzureCredential function of the Azure Identity module to authenticate a ResourceClient.
cred, err := azidentity.NewDefaultAzureCredential(nil)
if err != nil {
// handle error
}
client := armresources.NewResourcesClient(armcore.NewDefaultConnection(cred, nil), "<subscriptionId>")
Replace <subscriptionId> with the subscription ID of the subscription you want to authenticate with.
Key points:
- You can authenticate a service principal without using environment variables. To learn more, check out Authenticating a service principal with a client secret or Authenticating a service principal with a client certificate.
4. Create a resource group tag (sample)
Use the following code sample to verify that your service principal authenticates to Azure and has the appropriate permissions to the resource group.
Create a new directory called
go-on-azurein your home directory.mkidr ~/go-on-azureChange to the
go-on-azuredirectory.cd ~/go-on-azureRun
go mod initto create thego.modfile.go mod init go-on-azureRun
go getto install the required Go modules.go get "github.com/Azure/azure-sdk-for-go/sdk/azidentity" go get "github.com/Azure/azure-sdk-for-go/sdk/resources/armresources" go get "github.com/Azure/azure-sdk-for-go/sdk/azcore" go get "github.com/Azure/azure-sdk-for-go/sdk/armcore"Create a file named
main.goand add the following code.package main // Import key modules. import ( "context" "log" "github.com/Azure/azure-sdk-for-go/sdk/armcore" "github.com/Azure/azure-sdk-for-go/sdk/azcore" "github.com/Azure/azure-sdk-for-go/sdk/azidentity" "github.com/Azure/azure-sdk-for-go/sdk/resources/armresources" ) // Define key global variables. var ( ctx = context.Background() subscriptionId = "<subscriptionId>" resourceGroupName = "go-on-azure" // !! IMPORTANT: Change this to a unique name in your subscription. ) func addResourceGroupTag(ctx, connection *armcore.Connection) (armresources.ResourceGroupResponse, error) { rgClient := armresources.NewResourceGroupsClient(connection, subscriptionId) update := armresources.ResourceGroupPatchable{ Tags: map[string]*string{ "new": to.StringPtr("tag"), }, } return rgClient.Update(ctx, resourceGroupName, update, nil) } // Define the standard 'main' function for an app that is called from the command line. func main() { // Create a credentials object. cred, err := azidentity.NewDefaultAzureCredential(nil) if err != nil { log.Fatalf("Failed to configure credential: %+v", err) } // Establish a connection with the Azure subscription. conn := armcore.NewDefaultConnection(cred, &armcore.ConnectionOptions{ Logging: azcore.LogOptions{ IncludeBody: true, }, }) // Call your function to add a tag to your new resource group. updatedRG, err := addResourceGroupTag(ctx, conn) if err != nil { log.Fatalf("Update of resource group failed: %+v", err) } log.Printf("Resource Group %s updated", *updatedRG.ResourceGroup.ID) }Replace
<subscriptionId>with the subscription ID of the subscription you want to authenticate with.Run the
go runcommand to add the tag to your resource group.go run main.goVerify the tag was added.
az group show --resource-group go-on-azure --query 'tags'