Pulumi with GitHub Actions crashing parallel workflows with error: [409] Conflict: Another update is currently in progress. (e.g. with renovate)

Pulumi with GitHub Actions crashing parallel workflows with error: [409] Conflict: Another update is currently in progress. (e.g. with renovate)

与 Pulumi 一起使用 GitHub Actions 是一次很棒的体验,因为 the good Actions provided. But I tend to run into problems, where multiple GitHub Action workflows run in parallel (e.g. when renovate is configured and tries to update the repositories dependencies). So either the first workflow wins and does it's job - and the others fail. Or every workflow fails (which also depends on the GitHub Action workflow design). Then I get errors like this (see the full log here):

#### :tropical_drink: `pulumi --non-interactive up`
Previewing update (dev)

View Live: https://app.pulumi.com/jonashackt/scmbreakoutpulumi/dev/previews/fbf45825-5d8f-45bc-ad3e-c55b7576313e


    pulumi:pulumi:Stack scmbreakoutpulumi-dev running 
    azure:core:ResourceGroup scm-breakout-rg-pulumi  
    azure:storage:Account scmbreakresources  
    azure:appservice:Plan asp-scmbreakoutrg  
    azure:storage:Container rawimages  
    azure:storage:Queue thumbnails  
    azure:storage:Container thumbnails  
 +  azure:appservice:AppService scmContactsApi create 
 +  azure:appservice:AppService scmResourceApi create 
 +  azure:appservice:FunctionApp scmFunctionApp create 
 +  azure:appservice:Slot scmResourceApiStg create 
    pulumi:pulumi:Stack scmbreakoutpulumi-dev  
 
Resources:
    + 4 to create
    7 unchanged

Updating (dev)

error: [409] Conflict: Another update is currently in progress.
To learn more about possible reasons and resolution, visit https://www.pulumi.com/docs/troubleshooting/#conflict

日志已经引出了一个很好的资源:https://www.pulumi.com/docs/troubleshooting/#conflict其实是app.pulumi.com提供的Pulumi状态管理的一个特性:

One of the services that pulumi.com provides is concurrency control. The service will allow at most one user to update a particular stack at a time.

所以在 app.pulumi.com 处只使用一个像默认 dev 这样的堆栈,它看起来像这样:

使用GitHub Actions 或其他CI/CD 平台,这成为一个障碍。我在这里看到 2 个选项:我们可以切换到另一个 Pulumi 状态管理后端(比如 the Local Filesystem Backend,它不会在 app.pulumi.com 上创建堆栈,而是在本地 CI 上创建堆栈。或者我们可以在 app.pulumi.com 上创建一个 GitHub Action 作业特定堆栈,其中堆栈以特定作业 ID 或其他名称命名。

因为我不介意在这里使用 app.pulumi.com - 并且如果出现问题也使用额外的日志 - 我想为第二个选项找到解决方案。 GitHub 动作工作流文件设计可以用以下步骤描述:

  1. Standard Pulumi GitHub Action pipeline:定义所需的变量,检查 repo,设置 nodejs 环境,包括。安装 npm 依赖项 - 最后使用 action-install-pulumi-cli 操作配置 Pulumi CLI。
  2. 使用 pulumi stack init github-${{ github.run_id }} 在 app.pulumi.com 上创建 Pulumi 堆栈,类似于 the github.run_id GitHub Action default context variable。此变量表示“存储库中每个 运行 的唯一编号。”
  3. 利用(或多个)pulumi/actions@v2 Action in version v2 (since only from v2 we have the stack-name configuration option) 并使用 stack-name: github-${{ github.run_id }}
  4. 配置 Pulumi app.pulumi.com 堆栈名称
  5. 使用最终 pulumi stack rm github-${{ github.run_id }} -y
  6. 删除 Pulumi app.pulumi.com 堆栈

完整的 GitHub 操作流程如下所示:

name: pulumi-preview-up

on: [push]

env:
  ARM_SUBSCRIPTION_ID: ${{ secrets.ARM_SUBSCRIPTION_ID }}
  ARM_CLIENT_ID: ${{ secrets.ARM_CLIENT_ID }}
  ARM_CLIENT_SECRET: ${{ secrets.ARM_CLIENT_SECRET }}
  ARM_TENANT_ID: ${{ secrets.ARM_TENANT_ID }}
  PULUMI_ACCESS_TOKEN: ${{ secrets.PULUMI_ACCESS_TOKEN }}

jobs:
  preview-up-destroy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2

      - name: In order to use the Pulumi v2 action, we need to setup the Pulumi project specific language environment
        uses: actions/setup-node@v2
        with:
          node-version: '14'

      - name: After setting up the Pulumi project specific language environment, we need to install the dependencies also (see https://github.com/pulumi/actions#example-workflows)
        run: npm install

      - name: Install Pulumi CLI so that we can create a GHA pipeline specific Pulumi Stack
        uses: pulumi/action-install-pulumi-cli@v1.0.1

      - name: Create GHA pipeline specific Pulumi Stack incl. Azure location
        run: |
          pulumi stack init github-${{ github.run_id }}
          pulumi config set azure:location WestEurope

      - uses: pulumi/actions@v2
        with:
          command: preview
          stack-name: github-${{ github.run_id }}

      - uses: pulumi/actions@v2
        with:
          command: up
          stack-name: github-${{ github.run_id }}

      - uses: pulumi/actions@v2
        with:
          command: destroy
          stack-name: github-${{ github.run_id }}

      - name: Remove the GHA pipeline specific Pulumi Stack
        run: |
          pulumi stack rm github-${{ github.run_id }} -y

现在 app.pulumi.com 概览在 运行 并行执行多个 GitHub 操作工作流时如下所示: