使用托管标识通过 Azure SDK for Go 进行身份验证

在本教程中,你将使用托管标识配置 Azure 虚拟机,以便使用 Azure SDK for Go 向 Azure 进行身份验证。

托管标识通过直接向 Azure 资源提供标识,使你无需管理凭据。 分配给标识的权限授予对支持托管标识的其他 Azure 资源的资源访问权限。 使你无需将凭据传递到应用程序。

按照本教程操作,将托管标识分配给虚拟机,并使用托管标识向 Azure 进行身份验证。

先决条件

  • Azure 订阅:如果没有 Azure 订阅,请在开始之前创建一个免费帐户。

1.配置环境

在开始之前,需要配置环境。

部署虚拟机

将一个虚拟机部署到 Azure。 运行 Go 代码,在该虚拟机的 Azure 密钥保管库中创建机密。

  1. 创建 Azure 资源组。

    az group create --name go-on-azure --location eastus
    

    --location 参数更改为适合你的环境的值。

  2. 创建 Azure 虚拟机。

    az vm create \
    --resource-group go-on-azure \
    --name go-on-azure-vm \
    --image canonical:ubuntuserver:19.04:latest \
    --admin-username azureuser \
    --admin-password <password>
    

    <password> 替换为你的密码。

要详细了解支持托管标识的其他服务,请参阅支持 Azure 资源托管标识的服务

部署密钥保管库实例

通过运行以下命令,创建新的 Azure 密钥保管库实例:

az keyvault create --location eastus --name `<keyVaultName>` --resource-group go-on-azure

<keyVaultName> 替换为全局唯一名称。

2. 创建托管标识

Azure 支持两种类型的托管标识:系统分配的托管标识和用户分配的托管标识。

系统分配的标识直接附加到 Azure 资源,并且仅限于该资源。 用户分配的标识是可以分配给一个或多个 Azure 资源的独立资源。

要详细了解系统分配的标识和用户分配的标识之间的区别,请参阅托管标识类型

选择以下选项之一:

选项 1:创建系统分配的标识

运行以下命令以创建系统分配的托管标识:

az vm identity assign -g go-on-azure -n go-on-azure-vm

选项 2:创建用户分配的标识

运行以下命令以创建用户分配的托管标识:

az identity create -g go-on-azure -n GoUserIdentity

az vm identity assign -g go-on-azure -n go-on-azure-vm --identities <UserIdentityId>

<UserIdentityId> 替换为托管用户标识的 ID。

要了解详细信息,请参阅使用 Azure CLI 在 Azure VM 上配置 Azure 资源托管标识

3. 为托管标识分配角色

创建托管标识后,可以分配角色以授予标识访问其他 Azure 资源的权限。 在本教程中,将 Key Vault Contributor 的内置角色分配给托管标识,以便 Go 应用程序可以在密钥保管库实例内创建机密。

选择以下选项之一:

选项 1:为系统分配的标识分配角色

运行以下命令,为系统分配的托管标识分配 Key Vault Contributor 角色:

#output system identity principal ID
az vm identity show --name go-on-azure-vm --resource-group go-on-azure --query 'principalId' -o tsv

#output key vault ID
scope=$(az keyvault show --name go-on-azure-kv --query id -o tsv)

az role assignment create --assignee '<principalId>' --role 'Key Vault Contributor' --scope '<keyVaultId>'

选项 2:为用户分配的标识分配角色

运行以下命令,为用户分配的托管标识分配 Key Vault Contributor 角色:

#output user identity principal ID
az identity show --resource-group go-on-azure --name GoUserIdentity --query 'principalId' -o tsv

#output key vault ID
az keyvault show --name go-on-azure-kv --query id -o tsv

az role assignment create --assignee '<principalId>' --role 'Key Vault Contributor' --scope '<keyVaultId>'

要详细了解内置角色,请查看 Azure 内置角色

4. 使用 Go 创建密钥保管库机密

接下来通过 SSH 登录到 Azure 虚拟机,安装 Go 并构建 Go 包。

在 Azure VM 上安装 Go

  1. 获取 Azure 虚拟机的公共 IP 地址。

    az vm show -d -g go-on-azure -n go-on-azure-vm --query publicIps -o tsv
    
  2. 通过 SSH 登录到 Azure VM。

    ssh azureuser@<public-ip>
    

    <public-ip> 替换为 Azure VM 的公共 IP 地址。

  3. 安装 Go

    sudo add-apt-repository ppa:longsleep/golang-backports;
    sudo apt update;
    sudo apt install golang-go -y
    

创建 Go 包

  1. 在主目录中生成名为 go-on-azure 的新目录。

    mkidr ~/go-on-azure
    
  2. 切换到 go-on-azure 目录。

    cd ~/go-on-azure
    
  3. 运行 go mod init 以创建 go.mod 文件。

    go mod init go-on-azure
    
  4. 运行 go get 以安装所需的 Go 模块。

    go get "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
    go get "github.com/Azure/azure-sdk-for-go/sdk/keyvault/azsecrets"
    
  5. 创建 main.go 文件并将以下代码复制到该文件中。

    package main
    
    import (
        "context"
        "fmt"
        "log"
        "os"
    
        "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
        "github.com/Azure/azure-sdk-for-go/sdk/keyvault/azsecrets"
    )
    
    func createSecret() {
        keyVaultName := os.Getenv("KEY_VAULT_NAME")
        secretName := "quickstart-secret"
        secretValue := "createdWithGO"
        keyVaultUrl := fmt.Sprintf("https://%s.vault.azure.net/", keyVaultName)
    
        cred, err := azidentity.NewDefaultAzureCredential(nil)
        if err != nil {
            log.Fatalf("failed to obtain a credential: %v", err)
        }
    
        client, err := azsecrets.NewClient(keyVaultUrl, cred, nil)
        if err != nil {
            log.Fatalf("failed to create a client: %v", err)
        }
    
        resp, err := client.SetSecret(context.TODO(), secretName, secretValue, nil)
        if err != nil {
            log.Fatalf("failed to create a secret: %v", err)
        }
    
        fmt.Printf("Name: %s, Value: %s\n", *resp.ID, *resp.Value)
    }
    
    func main() {
        createSecret()
    }
    
    

在运行代码前,请创建名为 KEY_VAULT_NAME 的环境变量。 将环境变量值设置为之前创建的 Azure 密钥保管库的名称。 替换为 <KeyVaultName> Azure 密钥库 实例的名称。

export KEY_VAULT_NAME=<KeyVaultName>

接下来,运行 go run 命令以创建密钥保管库机密。

go run main.go

验证密钥保管库机密是使用 Azure PowerShell、Azure CLI 还是 Azure 门户创建的。

后续步骤