Pulumi コマンド を GitHub Actions で実行する
背景
副業で 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-type
は urn: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/actions
を comment-on-pr: true
にします。Pulumi report の部分を展開すると差分が表示されます。
終わり
今回はとりあえず preview だけ実行できるようにしました。次は pulumi up
もコメントとかをトリガーにやってくれるようにしようと思います。
参考
Discussion