Cloud run functionデプロイにおけるgcloudとterraformの棲み分け
背景
Google Cloudのcloud function gen2で下記の構成でイベント駆動アーキテクチャを構築する際にterraformとgcloudによるCDパイプラインの責務で迷ったので備忘録として記録する。
CDパイプラインはGithub Actionsを利用したCloud run functionのソースコードを管理するリポジトリ単位のパイプラインとなっている。
Object put on Cloud strage -> Eventarc (contain PubSub) -> Cloud run function
最終的な管理構成
Terraformで管理する範囲
- Service Account周り
- Cloud run Function周り
- Eventarc周り
- Google Cloud Strageのリソース
gcloudコマンドでの管理(リポジトリのCDパイプラインでの管理)
- Cloud run function
- Cloud Run
- Docker build
- invokeされるEventarcとの連携
- Eventarc
- イベントの受信元のGoogle Cloud Strageとの連携
最終的なgcloudコマンド
gcloud functions deploy <FUNCTION_NAME> \
--region=<REGION> \
--runtime=go125 \
--source=. \ // ソースコードのroot
--service-account=<FUNCTION_SERVICE_ACCOUNT> \
--set-env-vars=<FUNCTION_ENVIRONMENT_VAR> \
--set-build-env-vars=GOOGLE_BUILDABLE=. \
--entry-point=<FUNCTION_ENTORY_POINT> \
--trigger-event-filters=type=google.cloud.storage.object.v1.finalized \
--trigger-event-filters=bucket=<TRIGGER_BUCKET> \
--trigger-location=<REGION> \
--trigger-service-account=<TRIGGER_SERVICE_ACCOUNT> \
--gen2 \
--project=<GCP_PROJECT_ID> \
上記のコマンドをCDパイプラインとして組み込み、stagingやproductionといった環境ごとに分かれているプロジェクトごとにリリースできるようにした。
経緯
当初はCloud run functionのみをCDパイプラインでデプロイし、その他のリソースは事前に
terraformで作成/管理しようと思っていた。
AWSだとAWS Lambdaが似たような構成を取れる。例えばterraformでLambdaの箱だけを構築し、初期リリースを行い、その後lambrollなどのライブラリを用いて対象のLambdaに上書きデプロイをする。
こうすることで基本的なLambdaの設定や、SQSやStepFunctionなどのトリガーとの連携を全てterraformで管理でき、一元管理できる。
しかし、Google CloudのCloud run functionにはLambdaのように箱だけ作るという概念は存在せず、Cloud Run上で稼働するため、当然Cloud Runのデプロイと大きく依存する。terraformでCloud Runやfunctionを先に構築してしまうと、gcloudで既存のリソースをターゲットとできない。
それならと、Cloud run functionを先にgcloudでリリースし、後からterraformでimportしてEventarcとの連携を構築しようと思った。しかし、gcloudでさまざまな設定を簡単に更新できてしまうため、CDパイプラインの修正や改修とterraformのコードが密に依存してしまい、二重管理になる手間が出てきてしまう。
上記の経緯で、色々調べるとgcloudコマンドはかなり良しなに関連リソースを構築してくれるので、gcloudとterraformの責任境界が交わらないラインを考えた結果、最終管理構成のような形に落ち着いた。
Discussion