Cloud Runの不要なリビジョンを削除するGitHub Actions
@Colt45s です。
私はアプリケーションのデプロイ先に Cloud Run をよく利用しており、だいたい以下の記事ような構成にすることが多いです。
GitHub で PR を作成した時に、Cloud Run にpr-PRの番号
でタグ付けしてデプロイしています。
URL マスクを <tag>-<service>.ドメイン
のように設定して NEG を作成し、 外部アプリケーションロードバランサーのバックエンドとしています。
Terraform でも設定できます。
SSL 証明書は Certificate Manager でワイルドカード証明書を管理しています。
terraform-google-modules
のサンプルが参考になったので紹介します。
このような構成にすることで <pr-PRの番号>-<Cloud Runのサービス名>.ドメイン
でアクセスすると
外部アプリケーションロードバランサー -> NEG -> タグ付けした Cloud Run という経路でトラフィックが流れるようになります。この記事では プレビュー環境
という名称で呼ぶことにします。
筆者はあまり使ったことがなく詳しくないのですが、利用したことがある読者は Vercel のプレビューデプロイメント をイメージしていただけると分かりやすいかもしれません。
また、PR がマージやクローズされた場合にはプレビュー環境を GitHub Actions でクリーンアップしています。Cloud Run のみの話だと PR 用に作られたリビジョンを削除したいです。
ですが、次の条件に一致するリビジョンは削除からプロテクトされています。
- トラフィックを受信できるリビジョン
- サービスの唯一のリビジョン
- サービスの最新リビジョン
まれに最小インスタンスを割り当てたプレビュー環境を用意したいことがあり、デプロイ時にブランチ名の prefix や suffix に特定の文字列が含まれていたら最小インスタンスを割り当ててデプロイする等の工夫を行ったりもできます。削除からプロテクトされた後に不要なリビジョンが残り続けることは開発費用の増加に繋がるため、トイルを避けつつ不要になったリビジョンを削除したいといったモチベーションがありました。
そこで GitHub Actions の定期実行ワークフローを作成することで狙い通りの効果が得られましたのでサンプルを紹介したいと思います。
ちなみに、Cloud Run の請求については以前、同僚の @shimabukuromeg がまとめてくれた記事が分かりやすいのでそちらを見てください。
main ブランチまたは Open な PR 以外の最小インスタンスが割り当てられた Cloud Run のリビジョンを削除するワークフローを毎週金曜の 19 時(JST)に実行するサンプルです。
name: Delete Billable Cloud Run Revisions
on:
workflow_dispatch:
schedule:
- cron: "0 10 * * 5"
permissions:
id-token: write
contents: write
pull-requests: write
env:
DEPLOY_GCP_WIP: <Workload Identity Provider>
DEPLOY_GCP_SA: <権限を借用するSA>
jobs:
delete-billable-revisions:
name: Delete Billable Revisions
runs-on: ubuntu-latest
steps:
- name: Checktout
uses: actions/checkout@v4
- name: List Opened PR Number
id: list_pr_number
shell: bash
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
pr_numbers=$(gh pr list --state=open --json number --jq 'map(.number | tostring)')
echo "$pr_numbers"
echo "pr_numbers=$pr_numbers" >> "$GITHUB_OUTPUT"
- name: Configure GCP
uses: google-github-actions/auth@v1
with:
workload_identity_provider: ${{ env.DEPLOY_GCP_WIP }}
service_account: ${{ env.DEPLOY_GCP_SA }}
- name: Delete
shell: bash
env:
PR_NUMBERS: ${{ steps.list_pr_number.outputs.pr_numbers }}
run: |
revisions=$(gcloud run revisions list --region asia-northeast1 --filter 'metadata.annotations."autoscaling.knative.dev/minScale"!=0' --format 'value(metadata.name)')
while IFS= read -r pr_number; do
revisions=$(echo "$revisions" | grep -vE "pr-$pr_number\$|main\$")
done <<< "$(echo "$PR_NUMBERS" | jq -r '.[]')"
{
echo "## Delete revisions"
echo "$revisions"
} > "$GITHUB_STEP_SUMMARY"
echo "$revisions" | xargs -I_ gcloud run revisions delete _ --quiet --async --region asia-northeast1
gcloud run revisions list
の filter
オプションをカスタマイズしていただくとプロジェクトの使い方にマッチした条件で削除できると思います。
GitHub Actions と Google Cloud のキーレスの認証はこの記事が詳しいです。
以上です。
応用して使っていただけると @Colt45s が飛び跳ねて喜びます。
次は弊社 SRE チームの @beaverjr です!
よろしくお願いします!
Discussion