从 Azure Bicep 创建容器注册表并在 Azure Devops 中的同一生成管道中将映像部署到此注册表

Creating container registry from Azure Bicep and deploying image to this registry in the same build pipeline in Azure Devops

我运行正在处理 Azure Devops 中的一个问题。关于这个问题,我有两个问题。问题是我有一个 Azure Bicep 模板,它在我的 Azure 订阅中的一个资源组中部署了一堆资源。

其中一个资源是 Azure 容器注册表 (ACR),我想在更新图像代码时将某个图像推送到该资源。现在我基本上想要实现的是我有一个单一的多阶段 Azure 构建管道,其中

  1. 资源通过 Azure Bicep 部署,之后
  2. 我自动构建镜像并将其推送到 (ACR)

现在的问题是,要将图像推送到 ACR,需要在 Azure Devops 中建立服务连接,这只能在 Azure Bicep 管道具有 运行 后通过门户进行。现在我发现我可以使用 Azure CLI 命令:az devops service-endpoint create 从命令行中的 .json 文件创建连接,这实际上意味着我可以添加一个 .json-文件,但是在 AZ bicep 构建之前我没有正确的凭据,并且可能必须在我的 json 文件中公开敏感的 Azure 帐户信息以创建连接(如果可能的话)。

这给我留下了两个问题:

  1. 实际上,这是一个人会做的事情,还是只有两条管道更有意义?一种用于基础设施即代码,一种用于应用程序代码。我认为最好能够一次部署所有内容,但我对 DevOps 还很陌生,无法真正找到这个问题的答案。
  2. 无论如何,这仍然可以在单个 Azure DevOps 管道中安全地实现吗?

问题 1 的答案。

根据我的经验,基础设施和应用程序一直是分开的。我们通常希望将这两者分开,以便于管理。例如,您可能想要单独测试 ACR 的一项新功能,例如将防火墙规则添加到 ACR 的新要求,或者可能更改复制设置,而不是每次 rebuilding/pushing 一个新图像。

另一方面,BAU 管道涉及每天或每周构建新图像。一个动作是 one-off 的东西,另一个更像是一个 BAU。您通常只想构建 ACR 而忘记它,只在需要时引用。

此外,ACR 最终可用于您将来拥有的许多其他应用程序管道的图像。所以你真的不想将它绑定到特定的应用程序管道。如果你想要一个面向未来的解决方案,我建议将它们分开,然后为不同的应用程序构建使用不同的管道。

通常最好将核心基础设施资源代码与 BAU 内容分开。

问题 2 的答案。

我不详细了解您 运行 管道的具体细节,但据我了解,关于公开敏感内容,我有两种处理方式(最佳做法)这个。

  1. 将包含敏感内容的文件作为安全文件保存在管道库中,需要时再取回。
  2. 将内容或任何机密保存在 Azure KeyVault 中,并在您的管道中阅读它们 运行。

我完全同意关于不在同一管道中执行所有操作的公认答案。

ACR 支持 RBAC,您可以授予服务主体 运行 您的管道 AcrPush 权限。这样您就无需创建另一个服务连接:

// container registry name
param registryName string

// role to assign
param roleId string = '8311e382-0749-4cb8-b61a-304f252e45ec' // AcrPush role

// objectid of the service principal
param principalId string

resource registry 'Microsoft.ContainerRegistry/registries@2021-12-01-preview' existing = {
  name: registryName
}

// Create role assignment
resource registryRoleAssignment 'Microsoft.Authorization/roleAssignments@2020-04-01-preview' = {
  name: guid(subscription().subscriptionId, resourceGroup().name, registryName, roleId, principalId)
  scope: registry
  properties: {
    roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleId)
    principalId: principalId
  }
}

在其他后续管道中,您可以 login 然后 buildAndPush 到容器注册表,而无需手动创建服务连接或存储任何其他机密:

steps:
...
- task: AzureCLI@2
  displayName: Connect to container registry
  inputs:
    azureSubscription: <service connection name>
    scriptType: pscore
    scriptLocation: inlineScript
    inlineScript: |
      az acr login --name <azure container registry name>

- task: Docker@2
  displayName: Build and push image
  inputs:
    command: buildAndPush
    repository: <azure container registry name>.azurecr.io/<repository name>
    ...

我的答案实际上是关于不必创建您还必须单独维护的额外凭据集。