Pulumi、Terraform、Bicep 等是使开发人员和 IT 专业人员能够使用代码构建和部署基础设施到云的工具。基础设施即代码是使用您已经知道的工具和语言(在大多数情况下)实施复杂解决方案的好方法。

我们最近在#425Show 上邀请了 Sean Whitesell 向我们展示如何开始使用 Pulumi 和 Azure。如果您想观看视频,现在可以在 YouTube 上观看

本博客扩展了这些流,重点介绍了如何使用 Pulumi 和 Azure Key Vault 将基础架构安全地部署到 Azure。

在保护 Pulumi 中的敏感信息和机密时,主要有两种选择:

  1. 在部署时使用服务主体查询 Azure Key Vault

  2. 使用加密提供者来存储秘密

1.1 创建用于部署的服务主体:

首先,我们需要在 Azure AD 中创建一个服务主体。打开 Azure CLI 并键入以下内容:

az login
az ad sp create-for-rbac -n pulumi-deployment-sp --scopes /subscriptions/<YourSubscriptionId>

进入全屏模式 退出全屏模式

结果应如下所示:

{
  "appId": "1fdd1348-ccb0-4ec5-9799-edd14dd72e13",
  "displayName": "pulumi-deployment-sp",
  "name": "http://pulumi-deployment-sp",
  "password": "<it's a secret>",
  "tenant": "e801a3ad-3690-4aa0-a142-1d77cb360b07"
}

进入全屏模式 退出全屏模式

确保此信息安全,因为我们稍后需要在设置中使用它

1.2 配置 Key Vault 访问策略

服务主体现在可用于部署资源,但无权访问我们的 Key Vault 机密。我们将使用 Key Vault 来存储密码、密钥和连接字符串等敏感信息,以解耦 Pulumi 代码和配置设置。这样一来,代码变得更加可移植,IT 管理员可以审核机密的使用情况,以确保没有恶意行为。

在 Azure 门户中,打开 Key Vault 并导航到 Access Policies 边栏选项卡。根据下图添加新策略:

[Alt](https://res.cloudinary.com/practicaldev/image/fetch/s--zsYp0iMc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev- to-uploads.s3.amazonaws.com/i/sct2ntapsp6kuijfh5ly.png)

服务主体现在应该能够从我们的 Key Vault 列出和获取机密

1.3 配置 Pulumi 使用服务主体对 Azure 进行身份验证

接下来,我们需要设置 Pulumi 使用服务主体,以便向 Azure 资源管理器进行身份验证以部署我们的资源。由于Pulumi在后台使用Terraform,所以我们需要配置的环境变量和这个TerraForm文档完全一样

在我们的 PowerShell 会话中(我不希望这些永久存储在我的机器上),我们使用创建服务主体时提供的输出信息设置以下环境变量:

$env:ARM_CLIENT_ID="<Service Principal App ID>"
$env:ARM_CLIENT_SECRET="<Service Principal secret/password>"
$env:ARM_SUBSCRIPTION_ID="<Subscription ID>"
$env:ARM_TENANT_ID="<Azure AD Tenant ID>"

进入全屏模式 退出全屏模式

1.4 实际代码

要在部署过程中访问我们的 Azure Key Vault 机密,我们可以使用以下代码:

import * as pulumi from "@pulumi/pulumi";
import * as azure from "@pulumi/azure";

interface Data{
    azurerm_key_vault: {
        id:string
    }
};

let config = new pulumi.Config();
let data = config.requireObject<Data>("data");

const sql_username_secret = azure.keyvault.getSecret({
    name: "pulumi-sql-username",
    keyVaultId: data.azurerm_key_vault.id
});

const sql_password_secret = azure.keyvault.getSecret({
    name: "pulumi-sql-password",
    keyVaultId: data.azurerm_key_vault.id
});

export const sql_username = sql_username_secret.then(secret => secret.value);
export const sql_password = sql_password_secret.then(secret => secret.value);

进入全屏模式 退出全屏模式

如果你想知道我们从哪里得到data对象,这是我们使用 Pulumi CLI 初始化的东西。或者,我们可以直接编辑Pulumi.<environment>.yaml。目前,data对象包含 Azure Key Vault 资源 ID,我们可以通过 Pulumi CLI 使用以下命令设置它:

 pulumi config set --path 'data.azurerm_key_vault.id' /subscriptions/<mySubscriptionId>/resourceGroups/<myResourceGroup>/providers/Microsoft.KeyVault/vaults/<myKeyVaultName>

进入全屏模式 退出全屏模式

运行此命令将更新Pulumi.dev.yaml文件,如下所示:

config:
  azure:environment: public
  azure:location: WestUS
  pulumiwithaad:data:
    azurerm_key_vault:
      id: /subscriptions/d801110....

进入全屏模式 退出全屏模式

如果我们使用上面提供的代码运行Pulumi up命令,我们应该会收到以下输出

[Alt](https://res.cloudinary.com/practicaldev/image/fetch/s--bc4Nwn7D--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev- to-uploads.s3.amazonaws.com/i/g4j7uw2gk42qkrzb8t8v.png)

2\。使用 Pulumi 的 KeyVault Secrets 提供程序

另一个选项,为了让我们的配置设置保密,是使用 Secrets Encryption Provider 来加密我们的敏感数据。默认情况下,这是由 Pulumi 服务开箱即用提供的,但有一个选项可以显式设置您自己的加密提供程序。可用的选项有:

  • 默认

  • 密码

  • awkms

  • 天蓝色

  • gcpkms

  • 哈希伏特

当然,我会选择使用 Azure Key Vault 提供程序,因为我可以使用托管标识或服务主体来运行我的部署任务。

实现这一点需要几个步骤。对于本地发展,我们需要:

2.1 通过 CLI 启用 Azure Key Vault 身份验证

首先,我们需要配置以下环境变量并将其设置为true。打开您将运行任务的 PowerShell 会话并执行以下命令:

$env:AZURE_KEYVAULT_AUTH_VIA_CLI = "true"

进入全屏模式 退出全屏模式

接下来,我们需要确保 Azure CLI 使用正确的服务主体。为此,我们可以运行以下命令。在同一个 PowerShell 会话中,使用以下命令登录到 Azure CLI:

az login --service-principal --username <Service Principal Client Id> --tenant <Azure AD Tenant Id> --password <Service Principal Client Secret>

进入全屏模式 退出全屏模式

或者,我们可以使用证书来验证我们的服务主体,这比传递凭据更安全。

2.2 配置Secrets Provider

接下来我们需要更新 Pulumi 以使用 Key Vault 作为秘密提供者。这可以通过在 Pulumi CLI 中运行以下命令来完成:

pulumi stack change-secrets-provider "azurekeyvault://<yourKeyVaultName>.vault.azure.net/keys/<TheKeyToUseForEncryptionDecryption>"

进入全屏模式 退出全屏模式

[Alt](https://res.cloudinary.com/practicaldev/image/fetch/s--b5dJcSR7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev- to-uploads.s3.amazonaws.com/i/jolz6fbf6dpz8pcrk98h.png)

2.3。更新 Key Vault 中的访问策略

如果我们现在尝试运行我们的 Pulumi 脚本,可以保证我们会收到“未经授权”的错误消息。这是因为我们的服务主体需要能够使用指定的 Key Vault 密钥来加密和解密数据。

[Alt](https://res.cloudinary.com/practicaldev/image/fetch/s--yzGBGl4j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev- to-uploads.s3.amazonaws.com/i/0s7y02pt7kfokvyc2l8u.png)

要修复此错误,我们需要按照下图更新 Azure Key Vault 访问策略:

[Alt](https://res.cloudinary.com/practicaldev/image/fetch/s--c4kAfAm7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev- to-uploads.s3.amazonaws.com/i/mj26bvi89zpdgvp8bobg.png)

  • 将 Key Vault 支持的机密添加到我们的配置文件

2.4 添加密码

随着 Pulumi 准备使用 Key Vault 作为其秘密提供者,我们现在可以在我们的代码中添加一个新秘密。打开 Pulumi CLI 并运行以下命令:

pulumi config set --secret someOtherSecret Hunter2!

这将在我们的Pulumi.dev.yaml文件中添加一个条目:pulumiwithaad:someOtherSecret以及对我们的 Secrets ProviderEncryptedKey 的引用

secretsprovider: azurekeyvault://<myKeyVault>.vault.azure.net/keys/pulumiKey
encryptedkey: aGxiU1Jq...<omitted for brevity>...VHVLNUE=
config:
  azure:environment: public
  azure:location: WestUS
  pulumiwithaad:data:
    azurerm_key_vault:
      id: /subscriptions/d8011108-23b2-40d8-8bc4-1f3f77abe795/resourceGroups/dotnetconf/providers/Microsoft.KeyVault/vaults/cmdeploymentdemo
  pulumiwithaad:someOtherSecret:
    secure: v1:6oxydcsaDaemg43V:fV6Oy11srnDjxdlRVwsPb5xMo6nS/y6Q

进入全屏模式 退出全屏模式

如果我们运行pulumi preview那么我们可以看到我们的秘密是如何按预期设置的:

[Alt](https://res.cloudinary.com/practicaldev/image/fetch/s--YkuuEIMI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev- to-uploads.s3.amazonaws.com/i/7p8kk888l3h1njh6gax4.png)

在我们的 Pulumi 代码中,我们可以通过调用来引用秘密:

const kvSecret = config.requireSecret("someOtherSecret");

进入全屏模式 退出全屏模式

我们现在已准备好将我们的 SQL 服务器部署到 Azure!我们开工吧:

Pulumi up

[Alt](https://res.cloudinary.com/practicaldev/image/fetch/s--H-LMZ930--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https:// dev-to-uploads.s3.amazonaws.com/i/52rnnt3k0wk5oz1s2mgg.gif)

有用!

源代码

你可以在这个GitHub repo上找到这个示例代码

总结

Sean 在节目中表现出色,我们学到了很多关于 Pulumi 以及如何将它与 Azure AD 一起使用的知识。这篇博文进一步解释了如何通过删除机密并依靠服务主体和 Azure 托管标识向 Azure 进行身份验证和运行部署来进一步锁定和保护 DevOps 管道。如果您有任何问题,请在评论中告诉我们!

Logo

CI/CD社区为您提供最前沿的新闻资讯和知识内容

更多推荐