😪

Pulumi コマンド を GitHub Actions で実行する

2024/05/18に公開

背景

副業で Pulumi を使っています。
プロバイダーなどのパッケージのバージョン更新をサボっていたのですが、対応しようと思い Renovate で更新するようにしました。しかし、PR が来た時点では Pulumi の差分が分かりません。ローカルで pulumi preview を実行して差分がないことを毎回確認するのは面倒なので GitHub Actions で pulumi preview を実行して PR のコメントで差分を表示してもらうことにしました。

環境

Pulumi Cloud
Pulumi + TypeScript
Google Cloud

実装していく

複数環境(Stack)で preview を実行したいので Reusable workflow を使います。

# pulumi-preview-base.yaml

name: Pulumi Preview Base

on:
  workflow_call:
    secrets:
      google_cloud_project_id:
        required: true
      google_cloud_workload_identity_provider:
        required: true
      pulumi_stack_name:
        required: true

jobs:
  pulumi-preview:
    name: Pulumi Preview
    runs-on: ubuntu-latest
    permissions:
      contents: read
      pull-requests: write
      id-token: write
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@v4.1.4

      - id: auth
        uses: google-github-actions/auth@v2.1.2
        with:
          project_id: ${{ secrets.google_cloud_project_id }}
          workload_identity_provider: ${{ secrets.google_cloud_workload_identity_provider }}

      - uses: actions/setup-node@v4.0.2
        with:
          node-version-file: package.json
          cache: 'npm'
          cache-dependency-path: package-lock.json

      - run: npm ci

      - uses: pulumi/auth-actions@v1.0.0
        with:
          organization: org-name
          requested-token-type: urn:pulumi:token-type:access_token:personal
          scope: user:user-name

      - uses: pulumi/actions@v5.2.3
        with:
          stack-name: ${{ secrets.pulumi_stack_name }}
          command: preview
          refresh: true
          comment-on-pr: false
          github-token: ${{ secrets.GITHUB_TOKEN }}
# pulumi-preview.yaml

name: Pulumi Preview

on:
  pull_request:

jobs:
  pulumi-preview-stg:
    uses: ./.github/workflows/pulumi-preview-base.yaml
    secrets:
      google_cloud_project_id: ${{ secrets.STG_GOOGLE_CLOUD_RROJECT_ID }}
      google_cloud_workload_identity_provider: ${{ secrets.STG_GOOGLE_CLOUD_WORKLOAD_IDENTITY_PROVIDER }}
      pulumi_stack_name: ${{ secrets.STG_PULUMI_STACK_NAME }}

  pulumi-preview-prod:
    uses: ./.github/workflows/pulumi-preview-base.yaml
    secrets:
      google_cloud_project_id: ${{ secrets.PROD_GOOGLE_CLOUD_PROJECT_ID }}
      google_cloud_workload_identity_provider: ${{ secrets.PROD_GOOGLE_CLOUD_WORKLOAD_IDENTITY_PROVIDER }}
      pulumi_stack_name: ${{ secrets.PROD_PULUMI_STACK_NAME }}

pulumi/auth-actions を利用して OIDC を行うのでそのための設定をします。Team プランだと Organization Access Token は発行できない(Enterprise 以上の機能)ため、requested-token-typeurn:pulumi:token-type:access_token:personalにしています。こちらを参考に設定します。

Google Cloud の権限が必要なので google-github-actions/auth を使います。これに伴い先に必要なリソースを作成しておきます。今回は推奨されている Direct Workload Identity Federation を使います。

const workloadIdentityPool = new gcp.iam.WorkloadIdentityPool(
  'github',
  {
    workloadIdentityPoolId: 'github',
    displayName: 'GitHub Actions Pool',
  }
);

const workloadIdentityPoolProvider = new gcp.iam.WorkloadIdentityPoolProvider(
  'github',
  {
    workloadIdentityPoolId: workloadIdentityPool.workloadIdentityPoolId,
    workloadIdentityPoolProviderId: `${repositoryOwner.toLowerCase()}-repo`,
    displayName: `${repositoryOwner} GitHub repo`,
    oidc: {
      issuerUri: 'https://token.actions.githubusercontent.com',
    },
    attributeMapping: {
      'attribute.repository_owner': 'assertion.repository_owner',
      'attribute.actor': 'assertion.actor',
      'attribute.repository': 'assertion.repository',
      'google.subject': 'assertion.sub',
    },
    attributeCondition: `assertion.repository_owner == '${repositoryOwner}'`,
  }
);

const workloadIdentityPoolViewerRole = new gcp.projects.IAMMember(
  'github-workload-identity-pool-viewer-role',
  {
    project: gcpProject,
    role: 'roles/viewer',
    member: pulumi.interpolate`principalSet://iam.googleapis.com/${workloadIdentityPool.name}/attribute.repository/${repositoryOwner}/${repositoryName}`,
  }
);

preview 結果をコメントに残す方法は2つあり、Pulumi GitHub App か GitHub Actions Bot のどちらかを使います。

今回は Pulumi GitHub App を使いました。Pulumi Cloud を使っているのでリンクを貼ってくれるこちらにしておきました。

GitHub Actions Bot の場合は pulumi/actionscomment-on-pr: true にします。Pulumi report の部分を展開すると差分が表示されます。

終わり

今回はとりあえず preview だけ実行できるようにしました。次は pulumi up もコメントとかをトリガーにやってくれるようにしようと思います。

参考

https://www.pulumi.com/docs/using-pulumi/continuous-delivery/github-actions/
https://github.com/pulumi/actions
https://github.com/pulumi/auth-actions
https://github.com/google-github-actions/auth

Discussion