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

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

托管标识通过直接向 Azure 资源提供标识,使你无需管理凭据。 分配给标识的权限授予资源对支持托管标识的其他 Azure 资源的访问权限,无需在应用程序中传递凭据。 可以使用托管标识通过其他 Azure 资源对 Azure 托管的应用进行身份验证和授权。

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

先决条件

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

1.创建 Azure 资源

在开始之前,需要创建新的资源组、虚拟机和密钥保管库实例。

部署虚拟机

将一个虚拟机部署到 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:0001-com-ubuntu-server-jammy:22_04-lts:latest \
    --admin-username azureuser \
    --admin-password <password>
    

    <password> 替换为你的密码。

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

部署密钥保管库实例

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

az keyvault create --location eastus --name <keyVaultName> --resource-group go-on-azure --enable-rbac-authorization

<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 GoUserIdentity

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

3. 为托管标识分配角色

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

选择以下选项之一:

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

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

#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
az keyvault show --name <keyVaultName> --query id -o tsv

az role assignment create --assignee <principalId> --role "Key Vault Secrets Officer" --scope <keyVaultId>

在第二个命令中,替换为 <keyVaultName> 密钥保管库的名称。 在最后一个命令中,替换 <principalId><keyVaultId> 两个命令的输出。

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

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

#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 <keyVaultName> --query id -o tsv

az role assignment create --assignee <principalId> --role "Key Vault Secrets Officer" --scope <keyVaultId>

在第二个命令中,替换为 <keyVaultName> 密钥保管库的名称。 在最后一个命令中,替换 <principalId><keyVaultId> 两个命令的输出。

若要详细了解 Azure 密钥保管库中的内置角色,请参阅使用 Azure 基于角色的访问控制提供对密钥库密钥、证书和机密的访问权限。 若要详细了解 Azure 中的内置角色,请参阅 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 的新目录。

    mkdir ~/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/security/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/security/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)
        }
    
        params := azsecrets.SetSecretParameters{Value: &secretValue}
        resp, err := client.SetSecret(context.TODO(), secretName, params, 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()
    }
    
    
  6. 创建一个名为 KEY_VAULT_NAME 的环境变量。 替换为 <keyVaultName> Azure 密钥保管库实例的名称。

    export KEY_VAULT_NAME=<keyVaultName>
    
  7. 运行 go run 命令以创建密钥保管库机密。

    go run main.go
    

    成功后,输出类似于以下内容:

    Name: https://<keyVaultName>.vault.azure.net/secrets/quickstart-secret/0e0b941824c4493bb3b83045a31b2bf7, Value: createdWithGO
    

可以使用 Azure PowerShell、Azure CLI 或Azure 门户验证密钥保管库机密是否已创建。

注意

如果使用 Azure CLI 或 Azure PowerShell,则需要确保为 Azure 用户帐户分配了一个角色,该角色允许其读取密钥保管库中的机密,例如“密钥库机密办公室r”或“密钥库机密用户”。

5.清理资源

如果不想再使用本文中创建的 Azure 资源,最好将其删除。 删除未使用的资源有助于避免产生持续费用,并使订阅保持整洁。 删除本教程中使用的资源的最简单方法是删除资源组。

az group delete --name go-on-azure --force-deletion-types Microsoft.Compute/virtualMachines --yes

force-deletion-type 参数指示命令强制删除资源组中的 VM。 该 --yes 参数告知命令不要要求确认。

上述命令对资源组中的密钥保管库执行 软删除 。 若要永久将其从订阅中删除,请输入以下命令:

az keyvault purge --name <keyVaultName> --no-wait

<keyVaultName> 替换为你的密钥保管库名称。

后续步骤